同时使用多对多和一对多同一实体

时间:2011-11-22 15:04:08

标签: c# entity-framework many-to-many one-to-many

我在EF Code-First中有多对多的关联(如this问题中所述),我也希望对同一个实体使用一对多关系。问题是EF无法生成正确的数据库方案。代码:

public class A
{
  public int Id { get; set; }
  public string Name { get; set; }
  public virtual ICollection<B> ObjectsOfB { get; set; }
}

public class B
{
  public int Id { get; set; }
  public virtual A ObjectA { get; set; }
  public virtual ICollection<A> OtherObjectsOfA { get; set; }
}

当我删除B类的ObjectA属性时,会正确生成多对多关联。 生成不正确时,实体B获得2个外键到A,实体A获得1个外键到B(就像多对一关系一样)。

2 个答案:

答案 0 :(得分:16)

如果您有多个导航属性,则引用同一实体EF不知道另一个实体的逆导航属性属于何处。在您的示例中:A.ObjectsOfB是指B.ObjectA还是B.OtherObjectsOfA?两者都是可能的并且是有效的模型。

现在,EF不会抛出像“无法明确确定关系”之类的异常。相反,它决定B.ObjectA引用B中的第三个端点,该端点未作为模型中的导航属性公开。这将在表B中创建第一个外键。 B中的两个导航属性引用A中的两个端点,这两个端点也未在模型中公开:B.ObjectA创建表B中的第二个外键和{{1}在表B.OtherObjectsOfA中创建一个外键。

要解决此问题,您必须明确指定关系。

选项一(最简单的方法)是使用A属性:

InverseProperty

这定义public class A { public int Id { get; set; } public string Name { get; set; } [InverseProperty("OtherObjectsOfA")] public virtual ICollection<B> ObjectsOfB { get; set; } } 是与A.ObjectsOfB的多对多关系的一部分。

另一个选择是在Fluent API中完全定义关系:

B.OtherObjectsOfA

答案 1 :(得分:0)

如果表B具有表A的外键,则B类具有导航属性A和A具有导航属性ICollection<A>
如果表B与表A有多对多的关系,则A类必须具有ICollection<B>,而B类必须具有ICollection<A>

试试这个,也许这会澄清你对EF的要求。