此关联的主体端必须使用关系流式 API 或数据注释显式配置
Posted
技术标签:
【中文标题】此关联的主体端必须使用关系流式 API 或数据注释显式配置【英文标题】:The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations 【发布时间】:2013-06-22 19:54:05 【问题描述】:“必须使用关系流式 API 或数据注释显式配置此关联的主体端。”
更新/迁移数据库时,我在 Entity Framework 4.4 中遇到此错误,但我没有尝试指定 1:1 关系。我想要这样的东西:
public class EntityA
public int ID get; set;
public int EntityBID get; set;
[ForeignKey("EntityBID")]
public virtual EntityB EntityB get; set;
public class EntityB
public int ID get; set;
public Nullable<int> PreferredEntityAID get; set;
[ForeignKey("PreferredEntityAID")]
public virtual EntityA PreferredEntityA get; set;
其中 EntityA 必须有一个 EntityB 父级,而 EntityB 可以有一个首选的 EntityA 子级,但不是必须的。首选子级应该是与父级关联的子级之一,但我不知道如何在数据库中强制执行此操作。我计划以编程方式执行它。
我该如何解决这个错误,或者有什么更好的方法来完成这些关系?
【问题讨论】:
[ForeignKey("EntityAID")]
表示应该有EntityB.EntityAID
属性。您是否在样本中错过了它?
你的意思是[ForeignKey("PreferredEntityAID")]?
感谢您的关注。只是在我的例子中错过了它。我编辑了它。
我也遇到过这个问题,只是因为我在填充EntityB时,忘记将EntityA填充到B的导航属性中
【参考方案1】:
Entity Framework Code-First 约定假设EntityA.EntityB
和EntityB.PreferredEntityA
属于同一关系,并且是彼此的反向导航属性。因为这两个导航属性都是引用(不是集合),所以 EF 推断出一对一的关系。
由于您实际上需要两个一对多关系,因此您必须重写约定。对于您的模型,只有使用 Fluent API 才能实现:
modelBuilder.Entity<EntityA>()
.HasRequired(a => a.EntityB)
.WithMany()
.HasForeignKey(a => a.EntityBID);
modelBuilder.Entity<EntityB>()
.HasOptional(b => b.PreferredEntityA)
.WithMany()
.HasForeignKey(b => b.PreferredEntityAID);
(如果你使用它,你可以删除[ForeignKey]
属性。)
您不能指定一个映射来确保首选子项始终是关联的子项之一。
如果您不想使用 Fluent API 而只想使用数据注释,您可以在 EntityB
中添加一个集合属性,并使用 [InverseProperty]
属性将其关联到 EntityA.EntityB
:
public class EntityB
public int ID get; set;
public Nullable<int> PreferredEntityAID get; set;
[ForeignKey("PreferredEntityAID")]
public virtual EntityA PreferredEntityA get; set;
[InverseProperty("EntityB")] // <- Navigation property name in EntityA
public virtual ICollection<EntityA> EntityAs get; set;
【讨论】:
以上是关于此关联的主体端必须使用关系流式 API 或数据注释显式配置的主要内容,如果未能解决你的问题,请参考以下文章