C# 必须使用关系流畅 API 或数据注释显式配置此关联的主体端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17254724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:58:23  来源:igfitidea点击:

The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations

c#.netentity-framework-4associations

提问by lintmouse

"The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations."

“必须使用关系流畅 API 或数据注释显式配置此关联的主体端。”

I am getting this error in Entity Framework 4.4 when updating/migrating the database, but I am not trying to specify a 1:1 relationship. I want something like this:

更新/迁移数据库时,我在 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; }
}

where EntityA must have an EntityB parent, whereas EntityB can have a preferred EntityA child, but doesn't have to. The preferred child should be one of the children associated with the parent, but I don't know how to enforce this in the database. I'm planning on enforcing it programmatically.

其中 EntityA 必须有一个 EntityB 父级,而 EntityB 可以有一个首选的 EntityA 子级,但不是必须的。首选子项应该是与父项关联的子项之一,但我不知道如何在数据库中强制执行此操作。我计划以编程方式强制执行它。

How do I get around this error or what is a better way of accomplishing these relationships?

我如何解决这个错误或者有什么更好的方法来完成这些关系?

采纳答案by Slauma

Entity Framework Code-First conventions are assuming that EntityA.EntityBand EntityB.PreferredEntityAbelong to the same relationship and are the inverse navigation properties of each other. Because both navigation properties are references (not collections) EF infers a one-to-one relationship.

实体框架代码优先约定假设EntityA.EntityBEntityB.PreferredEntityA属于同一关系并且是彼此的反向导航属性。因为两个导航属性都是引用(不是集合),所以 EF 推断出一对一的关系。

Since you actually want two one-to-many relationships you must override the conventions. With your model it's only possible with Fluent API:

由于您实际上想要两个一对多的关系,因此您必须覆盖约定。对于您的模型,只能使用 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);

(If you use this you can remove the [ForeignKey]attributes.)

(如果您使用它,您可以删除[ForeignKey]属性。)

You cannot specify a mapping that would ensure that the preferred child is always one of the associated childs.

您不能指定可确保首选子项始终是关联子项之一的映射。

If you don't want to use Fluent API but only data annotations you can add a collection property in EntityBand relate it to EntityA.EntityBusing the [InverseProperty]attribute:

如果您不想使用 Fluent API 而只想使用数据注释,您可以添加一个集合属性EntityB并将其与EntityA.EntityB使用[InverseProperty]属性相关联:

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; }
}