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

本文关键字:API fluent 数据 注释 配置 关系 主体 关联 | 更新日期: 2023-09-27 18:19:35

"必须使用关系fluent API或数据注释显式配置此关联的主端。"

在更新/迁移数据库时,我在实体框架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子级,但不必。首选子级应该是与父级关联的子级之一,但我不知道如何在数据库中强制执行。我正计划以编程方式强制执行它。

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

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

实体框架代码优先约定假设EntityA.EntityBEntityB.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; }
}