EF Core Fluent API 具有继承的配置
EF Core Fluent API Configurations with Inheritance
EF CORE Fluent Api 单独文件中的配置在简单的 classes Ref #1 && Ref # 2 中工作正常。当实体继承自 KeyedEntity
或 AuditableEntity
时,问题就来了
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;}
}
Mapper 是这样的
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");
}
}
现在问题出现在继承自 AuditableEntity
的实体上。我需要从特定实体 class 以及 AuditableEntityMap
class 和 KeyedEntityMap
class 注册地图。
现在我可以忘记 Map Inheritance 并合并实体 class 中的所有复杂继承 Map,我不想这样做并尊重 DRY 。 复杂继承的问题是它没有注册我的实体映射
您可以通过多种方式实现基本实体配置的 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");
}
}
然后对于需要额外配置的特定实体:
public class Person : AuditableEntity<int>
{
public string Name { get; set; }
}
你会注册
public class PersonEntityMap : AuditableEntityMap<Person, int>
{
public override void Configure(EntityTypeBuilder<Person> builder)
{
base.Configure(builder);
// Properties
builder.Property(t => t.Name).IsRequired();
// etc...
}
}
EF CORE Fluent Api 单独文件中的配置在简单的 classes Ref #1 && Ref # 2 中工作正常。当实体继承自 KeyedEntity
或 AuditableEntity
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;}
}
Mapper 是这样的
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");
}
}
现在问题出现在继承自 AuditableEntity
的实体上。我需要从特定实体 class 以及 AuditableEntityMap
class 和 KeyedEntityMap
class 注册地图。
现在我可以忘记 Map Inheritance 并合并实体 class 中的所有复杂继承 Map,我不想这样做并尊重 DRY 。 复杂继承的问题是它没有注册我的实体映射
您可以通过多种方式实现基本实体配置的 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");
}
}
然后对于需要额外配置的特定实体:
public class Person : AuditableEntity<int>
{
public string Name { get; set; }
}
你会注册
public class PersonEntityMap : AuditableEntityMap<Person, int>
{
public override void Configure(EntityTypeBuilder<Person> builder)
{
base.Configure(builder);
// Properties
builder.Property(t => t.Name).IsRequired();
// etc...
}
}