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:
- 编号
- SomeAttribute1
- SomeAttribute2
这是我所期望的。然而,我遇到的问题是,我很可能稍后会向这个 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:
- 编号
- SomeAttribute1
- SomeAttribute2
- Child2Attribute1
- Child2Attribute2
- 判别器
我理解鉴别器的概念,但是我的问题是在添加 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 不是唯一的(即 Child1
和 Child2
可能有一个 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");
}
我有一个 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:
- 编号
- SomeAttribute1
- SomeAttribute2
这是我所期望的。然而,我遇到的问题是,我很可能稍后会向这个 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:
- 编号
- SomeAttribute1
- SomeAttribute2
- Child2Attribute1
- Child2Attribute2
- 判别器
我理解鉴别器的概念,但是我的问题是在添加 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 不是唯一的(即 Child1
和 Child2
可能有一个 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");
}