Entity Framework 仅为一个 Child 模型添加鉴别器列

Entity Framework Add Discriminator Column for Only One Child Model

我有一个 parent 模型,它是抽象的,因此无法创建它的实例,目前我有一个 child class 继承自它。例如,我有这样的东西:

public abstract class Parent {
     public virtual int Id { get; set; }
}

public class Child1 : Parent {
     public override int Id { get; set; }
     public string SomeAttribute1 { get; set; }
     public string SomeAttribute2 { get; set; }
}

我正在使用 entity framework 填充我的数据库模型,当我添加

public virtual IDbSet<Child1> Child1 { get; set; } 在我的上下文中,我得到以下 table 以下列:

Parent:

这是我所期望的。然而,我遇到的问题是,我很可能稍后会向这个 parent class 添加更多 children 模型,例如另一个 class 例如:

public class Child2 : Parent {
     public override int Id { get; set; }
     public string Child2Attribute1 { get; set; }
     public string Child2Attribute2 { get; set; }
}

当我将这个 child 模型添加到上下文中时,我的 Parent 列就会变成这样:

Parent:

我理解鉴别器的概念,但是我的问题是在添加 Child2 class 之前我的数据库中已经存在的所有 Child1 objects不会有鉴别器列,然后会有空值。

我想这些空的鉴别器值会导致以后尝试访问它们时出现问题,所以我的问题是,有没有办法在只有 1 个 child 实体的模型上强制使用鉴别器列?

或者是否有更好的方法抢先 handling/preparing 以便稍后添加更多 child classes?

或者有什么好的方法可以让这两个 child class 成为他们自己的 table?我从来没有用 Entity Framework 做过太多花哨的 OOP,所以我不确定他们处理这个问题的最佳方法是什么。

感谢您的帮助!

编辑

我研究了 3 种不同的继承模型:TPH、TPT 和 TPC。 TPH 不是适用于我的场景的模型,但是 TPT 和 TPC 都可以。正如我在答案中提到的,我让 TPT 工作,但是 TPC 是我的 use-case 的理想选择,因为我不一定 want/need 将 parent class 存储在数据库中(但在我的上下文中仍然喜欢它)。通过对我的代码进行以下更改,我设法使 TPC 几乎可以正常工作:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Child1>().Map(m =>
    {
        m.MapInheritedProperties();
        m.ToTable("Child1");
    });

    modelBuilder.Entity<Child2>().Map(m =>
    {
        m.MapInheritedProperties();
        m.ToTable("Child2");
    });
}

并将我的 parent 模型更改为:

public abstract class Parent {
    [DatabaseGenerated(DatabaseGenerationOption.Identity)]
    public virtual int Id { get; set; }
}

但是 然后 我看到的问题是 children 中填充的 ID 不是唯一的(即 Child1Child2 可能有一个 Id = 1,但这意味着有 2 个 Parent objects 的 Id = 1,这违反了唯一键约束。

有没有办法强制 auto-generated ID 在 children 中是唯一的?

由于 Bradley Uffner 的建议,我找到了问题的解决方案:

Table-Per-Type 通过简单地将父 class 添加到上下文中,然后为每个子 class 创建单独的表,就像这样添加:

public virtual IDbSet<Parent> Parents { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Child1>().ToTable("Child1");
     modelBuilder.Entity<Child2>().ToTable("Child2");
}