本文介绍了同时使用许多一对多和一种对多到同一个实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在EF代码优先使用many-to-many关联(如的),我想用一个一对多同一实体为好。问题是EF不会产生正确的数据库方案。代码:

I have a many-to-many association in EF Code-First (as explained in this question), and I want to use a one-to-many to the same entity as well. The problem is EF does not produce the right database scheme. Code:

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的对象A属性许多一对多关联正确生成。
当错误地生成,实体B得2外键A,和实体A得1外键B(像许多一对一的关系)。

When I remove the ObjectA property of class B the many-to-many association is generated correctly.When generated incorrectly, entity B gets 2 foreign keys to A, and entity A gets 1 foreign key to B (like a many-to-one relation).

推荐答案

如果你有一个以上的导航属性指的是同一个实体EF不知道从哪里上的其他实体逆导航属性属于。在您的例子:是否 A.ObjectsOfB 参考 B.ObjectA B.OtherObjectsOfA ?双方将有可能和一个有效的模式。

If you have more than one navigation property refering to the same entity EF does not know where the inverse navigation property on the other entity belongs to. In your example: Does A.ObjectsOfB refer to B.ObjectA or to B.OtherObjectsOfA? Both would be possible and a valid model.

现在,EF不会抛出一个异常,如不能确定关系明确什么的。相反,它决定了 B.ObjectA 指的是第三端点在 B 未在模型公开为导航属性。这将创建表的第一个外键 B 。在 B两个导航属性​​指两个端点在 A 这也不会在模型中暴露: B.ObjectA 在外币表中的第二个外键 B B.OtherObjectsOfA 创建表 A 外键。

Now, EF does not throw an exception like "cannot determine relationships unambiguously" or something. Instead it decides that B.ObjectA refers to a third endpoint in B which is not exposed as navigation property in the model. This creates the first foreign key in table B. The two navigation properties in B refer to two endpoints in A which are also not exposed in the model: B.ObjectA creats the second foreign key in table B and B.OtherObjectsOfA creates a foreign key in table A.

要解决这个问题,你必须明确地指定的关系。

To fix this you must specify the relationships explicitely.

选项之一(最简单的方法)是使用 InverseProperty 属性:

Option one (the easiest way) is to use the InverseProperty attribute:

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
    [InverseProperty("OtherObjectsOfA")]
    public virtual ICollection<B> ObjectsOfB { get; set; }
}

这定义了 A.ObjectsOfB B.OtherObjectsOfA A多到许多关系的一部分。

This defines that A.ObjectsOfB is part of a many-to-many relation to B.OtherObjectsOfA.

另一种选择是用流利的API完全定义的关系:

The other option is to define the relationships completely in 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
}

这篇关于同时使用许多一对多和一种对多到同一个实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 01:08