难以找到相关的搜索结果......
鉴于此模型:
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<B> Bs { get; set; }
public virtual ICollection<C> Cs { get; set; }
}
使用此配置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>().ToTable("As");
modelBuilder.Entity<B>().ToTable("Bs");
modelBuilder.Entity<C>().ToTable("Cs");
base.OnModelCreating(modelBuilder);
}
我在数据库中得到了这个结果:
问题:
是否不支持导航属性的继承?如果我将public string SomeSharedProperty { get; set; }
添加到A
,那么我希望该属性的列只显示在As
表中。
Customer_ID
和Bs
表中Cs
列的原因是什么?有没有办法告诉EF不映射那个继承的属性?
谢谢!
答案 0 :(得分:3)
首先,支持继承。但在这个特定情况下,似乎并不像你期望的那样。
由于关系数据库不支持继承,因为我们从面向对象编程中知道它,因此必须进行某种转换才能实现。
这是一系列博客文章,详细介绍了这个问题:
它还试图给出何时使用哪种策略的指导。
<强>更新强>
显然这比初看起来更棘手。您看到的内容很可能是由于循环引用:A -> B -> Customer -> Bs
。
Bs / C的CustomerID
列不是As表中的继承列。它实际上是Customer
类中指定的关系属性的表示形式:
public virtual ICollection<B> Bs { get; set; }
会在表B中生成可为空的 CustomerID
列。
public virtual ICollection<C> Cs { get; set; }
会在表C中生成可以为空的 CustomerID
列。
因此,这些可以为空的列用于表示关系Customer -> Bs
和Customer -> Cs
。它们的出现与Customer
类的A
属性无关。
您可以通过删除客户类的导航属性轻松进行检查。然后结果就是您所期望的: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<A> As { get; set; }
public IEnumerable<B> Bs { get { return this.As.OfType<B>(); } }
public IEnumerable<C> Cs { get { return this.As.OfType<C>(); } }
}