具有继承的 EF Core Fluent API 配置

JB'*_*B's 3 c# entity-framework entity-framework-core asp.net-core ef-core-2.0

单独文件中的 EF CORE Fluent Api 配置适用于简单的类Ref #1 && Ref #2。当实体继承自KeyedEntityAuditableEntity

class abstract KeyedEntity<TValue> {
      public TValue Id {get; set;}
}

class abstract  AuditableEntity<TValue> : KeyedEntityBase<TValue>{
      public DateTime DateCreated {get; set;}
      public DateTime DateModified {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

映射器是这样的

public class KeyedEntityMap<TEntity, TId>
    : IEntityTypeConfiguration<TEntity> where TEntity
    : KeyedEntityBase<TId> where TId : struct
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        // Primary Key
        builder.HasKey(t => t.Id);

        // Properties
        builder.Property(t => t.Id).HasColumnName("id").ValueGeneratedOnAdd();
    }
}

public class AuditableEntityMap<TEntity, TId>
    : IEntityTypeConfiguration<TEntity>    where TEntity 
    : AuditableEntity<TId>    where TId : struct
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        // Properties
        builder.Property(t => t.DateCreated).HasColumnName("DateCreated");
        builder.Property(t => t.DateModified).HasColumnName("DateModified");           
    }
}
Run Code Online (Sandbox Code Playgroud)

现在问题发生在继承自 的实体上AuditableEntity。我需要从该特定实体类以及AuditableEntityMap类和KeyedEntityMap类中注册 Map 。

现在我可以忘记 Map Inheritance 并合并实体类中的所有复杂继承 Maps ,我不想这样做并尊重DRY复杂继承的问题是它没有注册我的实体映射

Iva*_*oev 7

有几种方法可以实现基本实体配置的 DRY。

最接近您当前设计的一点是简单地遵循配置类中的实体层次结构:

public class KeyedEntityMap<TEntity, TId> : IEntityTypeConfiguration<TEntity>
    where TEntity : KeyedEntityBase<TId>
    where TId : struct
{
    public virtual void Configure(EntityTypeBuilder<TEntity> builder)
    //       ^^^
    {
        // Primary Key
        builder.HasKey(t => t.Id);

        // Properties
        builder.Property(t => t.Id).HasColumnName("id").ValueGeneratedOnAdd();
    }
}

public class AuditableEntityMap<TEntity, TId> : KeyedEntityMap<TEntity, TId>
    //                                                 ^^^
    where TEntity : AuditableEntity<TId>
    where TId : struct
{
    public override void Configure(EntityTypeBuilder<TEntity> builder)
    //       ^^^
    {
        base.Configure(builder); // <<<
        // Properties
        builder.Property(t => t.DateCreated).HasColumnName("DateCreated");
        builder.Property(t => t.DateModified).HasColumnName("DateModified");           
    }
}
Run Code Online (Sandbox Code Playgroud)

然后对于需要额外配置的特定实体:

public class Person : AuditableEntity<int>    
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你会注册

public class PersonEntityMap : AuditableEntityMap<Person, int>
{
    public override void Configure(EntityTypeBuilder<Person> builder)
    {
        base.Configure(builder);
        // Properties
        builder.Property(t => t.Name).IsRequired();
        // etc...
    }
}
Run Code Online (Sandbox Code Playgroud)