实体框架核心2.0:如何一次配置抽象基类 [英] Entity Framework Core 2.0: How to configure abstract base class once

查看:38
本文介绍了实体框架核心2.0:如何一次配置抽象基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本模型:

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

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

Then a model which extends the base model defined above:

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

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

Then I have defined configuration classes for each:

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类:

Now, I have the following Context 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类中定义的Status模型配置应用于所有扩展到该模型的模型(此示例中只有一个:Item).我想避免每次使用时都定义相同的状态模型配置.状态模型本质上将是与每个Item记录关联的元数据(即数据库中的一个Item表包含在两个模型中定义的所有属性;仅此而已,无所不包).

I'm trying to figure out how to apply the Status model configurations defined in the StatusConfiguration class to all the models that extend to it (only one in this example: Item). I would like to avoid defining the same Status model configuration every time it gets used. The Status model will essentially be meta data associated with each Item record (i.e. one Item table in database containing all properties defined in both models; nothing more, and nothing less).

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

For example, my current implementation is the following ItemConfiguration class without using the 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);
    }
}

该当前实现可以正常运行,并且可以按预期迁移到数据库.我只是在寻找一种更易于管理的方式.

That current implementation works correctly and migrates to the database as intended. I'm simply looking for a more manageable way going forward.

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

My assumption is that I could extend the ItemConfiguration class to include the StatusConfiguration class but cannot find an example of that method online. I'm hoping someone with a little more experience could kindly point me in the right direction?

让我知道其他信息是否有帮助.

Let me know if additional information would be helpful.

推荐答案

如果我正确理解,Status只是一个基类,而不是参与

If I understand correctly, the Status is just a base class and not a base entity participating in Database Inheritance.

在这种情况下,切勿直接在实体模型和配置内部直接引用Status类,即没有DbSet<Status>,没有类型为StatusICollection<Status>的导航属性,没有modelBuilder.Entity<Status>()调用且没有IEntityTypeConfiguration<Status>.

In such case it's important to never refer to Status class directly inside entity model and configuration, i.e. no DbSet<Status>, no navigation properties of type Status or ICollection<Status>, no modelBuilder.Entity<Status>() calls and no IEntityTypeConfiguration<Status>.

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

Instead, you always have to refer to the concrete types inheriting from the Status. In order to reuse configuration code, you should use constrained generic methods or classes and pass the concrete entity types.

由于您使用的是IEntityTypeConfiguration类,所以最自然的做法是使您的StatusConfiguration类具有通用性:

Since you are using IEntityTypeConfiguration classes, probably the most natural is to make your StatusConfiguration class generic:

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

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

and let derived entity configuration classes derive from it:

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

这篇关于实体框架核心2.0:如何一次配置抽象基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆