我在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(就像多对一关系一样)。
答案 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的要求。