Mar*_*ijn 6 c# many-to-many entity-framework one-to-many
我在EF Code-First中有一个多对多的关联(正如本问题中所解释的那样),我也希望对同一个实体使用一对多关系.问题是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; }
}
Run Code Online (Sandbox Code Playgroud)
当我删除B类的ObjectA属性时,会正确生成多对多关联.当生成不正确时,实体B获得2个外键到A,实体A获得1个外键到B(如多对一关系).
Sla*_*uma 16
如果您有多个导航属性引用同一实体,则EF不知道另一个实体上的反向导航属性所属的位置.在您的示例中:是否A.ObjectsOfB引用B.ObjectA或B.OtherObjectsOfA?两者都是可能的并且是有效的模型.
现在,EF不会抛出像"无法明确地确定关系"之类的异常.相反,它决定B.ObjectA引用第三个端点,B其中未在模型中公开为导航属性.这将在表中创建第一个外键B.这两个导航性质B是指两个端点在A其中也没有在模型中暴露:B.ObjectA外币在表中的第二外键B和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; }
}
Run Code Online (Sandbox Code Playgroud)
这定义了它A.ObjectsOfB是多对多关系的一部分B.OtherObjectsOfA.
另一种选择是在Fluent API中完全定义关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.HasMany(a => a.ObjectsOfB)
.WithMany(b => b.OtherObjectsOfA)
.Map(x =>
{
x.MapLeftKey("AId");
x.MapRightKey("BId");
x.ToTable("ABs");
});
modelBuilder.Entity<B>()
.HasRequired(b => b.ObjectA) // or HasOptional
.WithMany()
.WillCascadeOnDelete(false); // not sure if necessary, you can try it
// without if you want cascading delete
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4306 次 |
| 最近记录: |