是否支持导航属性的inheritance?

难以找到相关的搜索结果……

鉴于此模型:

public abstract class A { public int ID { get; set; } public int CustomerID { get; set; } public virtual Customer Customer { get; set; } } public class B : A { } public class C : A { } public class Customer { public int ID { get; set; } public virtual ICollection Bs { get; set; } public virtual ICollection Cs { get; set; } } 

使用此配置:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().ToTable("As"); modelBuilder.Entity().ToTable("Bs"); modelBuilder.Entity().ToTable("Cs"); base.OnModelCreating(modelBuilder); } 

我在DB中得到这个结果:

数据库

题:

是否不支持导航属性的inheritance? 如果我添加public string SomeSharedProperty { get; set; } public string SomeSharedProperty { get; set; } 然后正如我所期望的那样,该属性的列只出现在As表中。

BsCs表中的Customer_ID列有什么原因? 有没有办法告诉EF不映射那个inheritance的属性?

谢谢!

首先,支持inheritance。 但在这个特定情况下似乎并不像你期望的那样。

由于关系数据库不支持inheritance,因为我们从面向对象编程中知道它,因此必须进行某种转换才能实现。

这是一系列博客文章,详细介绍了这个问题:

  • 每个层次结构的表
  • 每种类型的表
  • 每class表

它还试图给出何时使用哪种策略的指导。

UPDATE
显然这比初看起来更棘手。 你看到的很可能是由于循环引用: A -> B -> Customer -> Bs

Bs / Cs的CustomerID列不是As表中的inheritance列。 它实际上是Customer类上指定的关系属性的表示:

 public virtual ICollection Bs { get; set; } 

结果是表B上空的 CustomerID列。

 public virtual ICollection Cs { get; set; } 

得到表C中可空的 CustomerID列。

因此,那些可以为空的列用于表示Customer -> BsCustomer -> Cs 。 它们的外观与A类的Customer属性无关。

您可以通过删除客户类的导航属性轻松地进行检查。 然后结果就是您所期望的:A表上的CustomerID列和B / C表上没有CustomerID列。

因此,为了解决这个问题,您需要具体告诉EF如何解决循环引用。 不确定这是否可行,我担心您需要省略Customer上的Bs / Cs属性并编写LINQ查询来检索信息。

如果您需要Customer类上的这些属性,您可以这样做:

 public class Customer { public int ID { get; set; } // this is necessary to have access to the related Bs/Cs // also it cant be private otherwise EF will not overload it properly public virtual ICollection As { get; set; } public IEnumerable Bs { get { return this.As.OfType(); } } public IEnumerable Cs { get { return this.As.OfType(); } } }