是否支持导航属性的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
表中。
Bs
和Cs
表中的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 -> Bs
和Customer -> 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 (); } } }