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

Posted

技术标签:

【中文标题】Entity Framework Core 2.0:如何配置一次抽象基类【英文标题】:Entity Framework Core 2.0: How to configure abstract base class once 【发布时间】:2018-10-04 01:07:49 【问题描述】:

我有一个基础模型:

public abstract class Status

     public string updateUserName  get; set; 

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

public class Item : Status

     public int Id  get; set; 
     public string Description  get; set; 

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

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);
    

现在,我有以下 Context 类:

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 类中定义的 Status 模型配置应用到所有扩展到它的模型(本示例中只有一个:Item)。我想避免每次使用时都定义相同的状态模型配置。 Status 模型本质上是与每个 Item 记录相关联的元数据(即数据库中的一个 Item 表,其中包含两个模型中定义的所有属性;不多也不少)。

例如,我当前的实现是下面的 ItemConfiguration 类,没有使用 StatusConfiguration 类:

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 类以包含 StatusConfiguration 类,但在网上找不到该方法的示例。我希望有更多经验的人能给我指出正确的方向吗?

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

【问题讨论】:

【参考方案1】:

如果我理解正确,Status 只是一个基类,而不是参与Database Inheritance 的基实体

在这种情况下,永远不要在实体模型和配置中直接引用Status 类,即没有DbSet&lt;Status&gt;,没有StatusICollection&lt;Status&gt; 类型的导航属性,没有modelBuilder.Entity&lt;Status&gt;() 调用,也没有@ 987654329@.

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

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

public class StatusConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : Status

    public virtual void Configure(EntityTypeBuilder<TEntity> builder)
    
        builder.Property(c => c.updateUserName).IsRequired().HasMaxLength(50);
    

并让派生的实体配置类从中派生:

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);
    

【讨论】:

你一针见血。我专门在寻找如何实现该受约束的泛型方法并传递具体的实体类型。非常感谢您的宝贵时间! @Ivan 如果不利用IEntityTypeConfiguration&lt;TEntity&gt; ?***.com/questions/53275567/… 我该怎么做 @ibubi 我已经在那里发布了答案。 谢谢你!我正在尝试但无法使其正常工作。我最初错过了“base.Configure ...”条目,添加了它,一切都很完美。 很好的答案 - 这对我帮助很大。谢谢!

以上是关于Entity Framework Core 2.0:如何配置一次抽象基类的主要内容,如果未能解决你的问题,请参考以下文章

在 Entity Framework Core 2.0 中执行存储过程

与 Entity Framework Core 2.0 的一对零关系

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

Entity Framework Core 2.0 Add-Migration 不会创建任何迁移文件

如何告诉 Entity Framework 我的 ID 列是自动递增的(AspNet Core 2.0 + PostgreSQL)?

如何防止 Entity Framework Core 2.0 重命名生成类中的表和列(数据库优先)