Entity Framework Core 2.0:如何配置一次抽象基class

Entity Framework Core 2.0: How to configure abstract base class once

我有一个基础模型:

public abstract class Status
{
     public string updateUserName { get; set; }
}

然后是一个扩展上面定义的基本模型的模型:

public class Item : Status
{
     public int Id { get; set; }
     public string Description { get; set; }
}

然后我为每个定义了配置classes:

public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
    public void Configure(EntityTypeBuilder<Item> builder)
    {
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
    }
}

public class StatusConfiguration : IEntityTypeConfiguration<Status>
{
    public void Configure(EntityTypeBuilder<Status> builder)
    {
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }

现在,我有以下上下文class:

public class TestDbContext : DbContext
{
    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
    {
    }

    public DbSet<Item> Item { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new ItemConfiguration());
    }
}

我正在尝试弄清楚如何将 StatusConfiguration class 中定义的 Status 模型配置应用到所有扩展到它的模型(本例中只有一个:Item)。我想避免在每次使用时都定义相同的 Status 模型配置。 Status 模型本质上是与每个项目记录关联的元数据(即数据库中的一个项目 table 包含两个模型中定义的所有属性;仅此而已)。

例如,我当前的实现是以下 ItemConfiguration class 而没有使用 StatusConfiguration class:

public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
    public void Configure(EntityTypeBuilder<Item> builder)
    {
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }
}

当前的实现工作正常并按预期迁移到数据库。我只是在寻找一种更易于管理的前进方式。

我的假设是我可以扩展 ItemConfiguration class 以包含 StatusConfiguration class 但无法在线找到该方法的示例。我希望有更多经验的人可以为我指明正确的方向?

如果其他信息有帮助,请告诉我。

如果我没理解错的话,Status只是一个基地class,并不是实体参与Database Inheritance的基地class。

在这种情况下,切勿直接在实体模型和配置中引用 Status class,即没有 DbSet<Status>Status 类型的导航属性或ICollection<Status>,没有 modelBuilder.Entity<Status>() 来电,也没有 IEntityTypeConfiguration<Status>

相反,您始终必须引用从 Status 继承的具体类型。为了重用配置代码,您应该使用 受约束的泛型 方法或 classes 并传递具体的实体类型。

由于您使用的是 IEntityTypeConfiguration classes,最自然的方法可能是使您的 StatusConfiguration class 通用:

public class StatusConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : Status
{
    public virtual void Configure(EntityTypeBuilder<TEntity> builder)
    {
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    }
}

并让派生实体配置 classes 从中派生:

public class ItemConfiguration : StatusConfiguration<Item>
{
    public override void Configure(EntityTypeBuilder<Item> builder)
    {
        base.Configure(builder); // <--
        builder.ToTable("Item", "dbo").HasKey(c => c.Id);
        builder.Property(c => c.Description).IsRequired().HasMaxLength(100);
    }
}