如何通过 DbContext 过滤批量注册 IEntityTypeConfiguration<>

How to filter Bulk register IEntityTypeConfiguration<> by DbContext

我在应用程序中有多个 DbContext 文件(还有多个数据库)。我想通过相关的 DbContext 过滤 IEntityTypeConfiguration 注册。

例如我不想在 FirstDbContext 或 Customer ref 中引用任何 Account 实体。在 SecondDbContext 中。

根据 documentation,我应该能够将过滤器作为第二个参数传递。

这里怎么走?

public class FirstDbContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
    public FirstDbContext (DbContextOptions<FirstDbContext > options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder builder)
    {            
        builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
        base.OnModelCreating(builder);
    }
}

public class SecondDbContext : DbContext
{
    public DbSet<Account> Accounts{ get; set; }
    public SecondDbContext (DbContextOptions<SecondDbContext > options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder builder)
    {            
        builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
        base.OnModelCreating(builder);
    }
}

public class CustomerConfiguration : IEntityTypeConfiguration<Customer>
{
    public void Configure(EntityTypeBuilder<Customer> builder)
    {
        builder.Property(p => p.Id).ValueGeneratedNever();

       // more options here
    }
}

public class AccountConfiguration : IEntityTypeConfiguration<Account>
{
    public void Configure(EntityTypeBuilder<Account> builder)
    {
        builder.Property(p => p.Id).ValueGeneratedNever();

       // more options here
    }
}

ModelBuilder 应该已经在 OnModelCreating 的开头发现了您的 DbSet。因此,您应该能够通过 IEntityTypeConfiguration 实现来过滤程序集类型。

var types = modelBuilder.Model
    .GetEntityTypes()
    .Select(t => t.ClrType)
    .ToHashSet();

modelBuilder.ApplyConfigurationsFromAssembly(
    Assembly.GetExecutingAssembly(), 
    t => t.GetInterfaces()
        .Any(i => i.IsGenericType 
            && i.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>) 
            && types.Contains(i.GenericTypeArguments[0]))
    );

虽然您可能需要不同的解决方案来避免多次扫描程序集的性能损失。