我有一个抽象的父模型,因此不能创建它的实例,而且目前我有一个继承它的子类。例如,我有这样的事情:
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; }
}
我正在使用实体框架来填充我的数据库模型,当我添加
时 public virtual IDbSet<Child1> Child1 { get; set; }
在我的上下文中,我得到下表,其中包含以下列:
父:
这是我所期待的。但是我遇到的问题是我很可能稍后会在这个父类中添加更多的子模型,例如:
public class Child2 : Parent {
public override int Id { get; set; }
public string Child2Attribute1 { get; set; }
public string Child2Attribute2 { get; set; }
}
当我将这个子模型添加到上下文中时,我的Parent
列会变为:
父:
我理解鉴别器的概念,但我的问题是在添加Child1
类之前我的数据库中已经存在的所有Child2
对象都没有鉴别器列,并且然后有空值。
我想这些空的鉴别器值会在以后试图访问它们时引起问题,所以我的问题是,有没有办法在只有1个子实体的模型上强制使用鉴别器列?
否则是否有更好的方法可以预先处理/准备在以后添加更多子课程?
或者是否有一个很好的方法让这两个子类成为他们自己的表?我从来没有用Entity Framework做过很多花哨的OOP,所以我不确定他们最好的方法来解决这个问题。
感谢您的帮助!
修改
我研究了3种不同的继承模型:TPH,TPT和TPC。 TPH不是适用于我的场景的模型,但是TPT和TPC都可以工作。正如我在答案中提到的,我得到了TPT工作,但是TPC非常适合我的用例,因为我不一定要/需要将父类存储在数据库中(但在我的上下文中仍然会喜欢它)。我设法使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");
});
}
并将我的父模型更改为:
public abstract class Parent {
[DatabaseGenerated(DatabaseGenerationOption.Identity)]
public virtual int Id { get; set; }
}
然而然后我看到的问题是,跨孩子填充的ID不是唯一的(即Child1
和Child2
都可能有Id = 1,但是这意味着有2个Parent
个对象,Id = 1,这违反了唯一的密钥约束。
有没有办法可以强制自动生成的ID在儿童中独一无二?
答案 0 :(得分:0)
由于Bradley Uffner的建议,我找到了解决问题的方法:
Table-Per-Type通过简单地将父类添加到上下文中然后为每个子类创建单独的表来实现这个技巧,因为它们被添加如下:
public virtual IDbSet<Parent> Parents { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Child1>().ToTable("Child1");
modelBuilder.Entity<Child2>().ToTable("Child2");
}