• 推荐 为每个模块定义单独的 接口和类.
    • 不推荐 在应用程序开发中使用延迟加载.
    • 不推荐DbContext 启用延迟加载.
    • 推荐 继承自IEfCoreDbContextDbContext 定义一个相应的 interface.
    • 推荐 添加 ConnectionStringName attributeDbContext 接口.
    • 推荐DbSet<TEntity> properties 添加到 DbContext 接口中,注意: 仅适用于聚合根. 例如:

    DbContext class

    • 推荐 DbContext 继承自 AbpDbContext<TDbContext> 类.
    • 推荐 添加 ConnectionStringName attributeDbContext 类.
    • 推荐 实现 DbContext 类实现其相应的接口. 例如:
    1. [ConnectionStringName("AbpIdentity")]
    2. public class IdentityDbContext : AbpDbContext<IdentityDbContext>, IIdentityDbContext
    3. {
    4. public DbSet<IdentityUser> Users { get; set; }
    5. public DbSet<IdentityRole> Roles { get; set; }
    6. public IdentityDbContext(DbContextOptions<IdentityDbContext> options)
    7. : base(options)
    8. {
    9. }
    10. //code omitted for brevity
    11. }
    • 推荐 添加静态 properties TablePrefixSchemaDbContext 类. 使用常量为其设置一个默认值. 例如:
    1. public static string TablePrefix { get; set; } = AbpIdentityConsts.DefaultDbTablePrefix;
    2. public static string Schema { get; set; } = AbpIdentityConsts.DefaultDbSchema;
    • 推荐 总是使用简短的 TablePrefix 值为模块在共享数据库中创建 unique table names. Abp 前缀是为ABP Core模块保留的.
    • 推荐 Schema 默认赋值为 null.

    Model Mapping

    • 推荐 重写 DbContextOnModelCreating 方法显式 配置所有实体. 例如:
    • 不推荐 直接在 OnModelCreating 方法中配置model, 而是为 ModelBuilder 定义一个 扩展方法. 使用ConfigureModuleName作为方法名称. 例如:
    1. public static class IdentityDbContextModelBuilderExtensions
    2. {
    3. public static void ConfigureIdentity(
    4. [NotNull] this ModelBuilder builder,
    5. {
    6. Check.NotNull(builder, nameof(builder));
    7. var options = new IdentityModelBuilderConfigurationOptions();
    8. optionsAction?.Invoke(options);
    9. builder.Entity<IdentityUser>(b =>
    10. {
    11. b.ToTable(options.TablePrefix + "Users", options.Schema);
    12. b.ConfigureByConvention();
    13. //code omitted for brevity
    14. });
    15. builder.Entity<IdentityUserClaim>(b =>
    16. {
    17. b.ToTable(options.TablePrefix + "UserClaims", options.Schema);
    18. b.ConfigureByConvention();
    19. //code omitted for brevity
    20. });
    21. //code omitted for brevity
    22. }
    23. }
    • 推荐 为每个Enttiy映射调用 b.ConfigureByConvention();(如上所示).
    • 推荐 通过继承 AbpModelBuilderConfigurationOptions 来创建 configuration Options 类. 例如:
    1. public class IdentityModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
    2. {
    3. public IdentityModelBuilderConfigurationOptions()
    4. : base(AbpIdentityConsts.DefaultDbTablePrefix, AbpIdentityConsts.DefaultDbSchema)
    5. {
    6. }
    7. }
    • 推荐EfCoreRepository<TDbContext,TEntity,TKey>继承 仓储并实现相应的仓储接口. 例如:
    • 推荐 使用 DbContext 接口而不是类来作为泛型参数.
    • 推荐 使用 GetCancellationToken 帮助方法将 cancellationToken 传递给EF Core. 例如:
    1. public virtual async Task<IdentityUser> FindByNormalizedUserNameAsync(
    2. string normalizedUserName,
    3. bool includeDetails = true,
    4. CancellationToken cancellationToken = default)
    5. {
    6. return await DbSet
    7. .FirstOrDefaultAsync(
    8. GetCancellationToken(cancellationToken)
    9. );
    10. }
    • 推荐 为具有 子集合 的聚合根创建 IQueryable<TEntity> 返回类型的 IncludeDetails 扩展方法. 例如:
    1. public static IQueryable<IdentityUser> IncludeDetails(
    2. this IQueryable<IdentityUser> queryable,
    3. bool include = true)
    4. {
    5. if (!include)
    6. {
    7. return queryable;
    8. }
    9. return queryable
    10. .Include(x => x.Roles)
    11. .Include(x => x.Logins)
    12. .Include(x => x.Claims)
    13. .Include(x => x.Tokens);
    14. }

    Module Class

    • 推荐 为Entity Framework Core集成包定义一个Module类.
    • 推荐 使用 AddAbpDbContext<TDbContext> 方法将 DbContext 添加到 IServiceCollection.
    • 推荐 将已实现的仓储添加到 AddAbpDbContext<TDbContext> 方法的options中. 例如:
    1. [DependsOn(
    2. typeof(AbpIdentityDomainModule),
    3. typeof(AbpEntityFrameworkCoreModule)
    4. )]
    5. public class AbpIdentityEntityFrameworkCoreModule : AbpModule
    6. {
    7. public override void ConfigureServices(ServiceConfigurationContext context)
    8. {
    9. context.Services.AddAbpDbContext<IdentityDbContext>(options =>
    10. {
    11. options.AddRepository<IdentityUser, EfCoreIdentityUserRepository>();
    12. options.AddRepository<IdentityRole, EfCoreIdentityRoleRepository>();
    13. });
    14. }