Entity Framework Core: 同一实体的多对多关系

24

我正在尝试使用同一个实体映射多对多关系。User实体具有一个IList<User>数据字段,用于存储用户的联系人/朋友信息:Contacts

public class User : DomainModel
{
    public virtual IList<User> Contacts { get; protected set; }
    //irrelevant code omitted
}
当我尝试使用流畅的API来映射这个多对多的关系时,它给了我一些麻烦。 显然,当我在user.Contacts属性上使用HasMany()时,它没有下一个要调用的WithMany()方法。 Visual Studio的Intellisense只显示WithOne()而不是WithMany()
modelBuilder.Entity<User>().HasMany(u => u.Contacts).WithMany() 
// gives compile time error: CS1061 'CollectionNavigationBuilder<User, User>' does not contain a definition for 'WithMany' and no extension method 'WithMany' accepting a first argument of type 

那么为什么会出现这种情况呢?是我在映射这个多对多关系时做错了什么吗?


你可以看一下这个链接:https://ef.readthedocs.io/en/latest/modeling/relationships.html#many-to-many - Raphaël Althaus
1个回答

27
所以为什么会发生这种情况?我有做错什么导致这个多对多的关系无法映射吗?
不,你没有做错任何事情。它只是不被支持。当前状态在这里
没有实体类来表示连接表的多对多关系还不被支持。但是,您可以通过包括一个实体类来表示连接表,并映射两个单独的一对多关系来表示多对多关系。
使用EF-Core,您应该为映射表创建实体,例如UserContacts。一个完整的示例在文档中,正如评论中提到的那样。我实际上没有测试过下面的代码,但它应该看起来像这样:
public class UserContacts
{
    public int UserId { get; set; } 
    public virtual User User { get; set; }

    public int ContactId { get; set; } // In lack of better name.
    public virtual User Contact { get; set; }
}

public class User : DomainModel
{
    public List<UserContacts> Contacts { get; set; }
}

和你的modelBuilder相关。

  modelBuilder.Entity<UserContacts>()
        .HasOne(pt => pt.Contact)
        .WithMany(p => p.Contacts)
        .HasForeignKey(pt => pt.ContactId);

    modelBuilder.Entity<UserContacts>()
        .HasOne(pt => pt.User)
        .WithMany(t => t.Contacts)
        .HasForeignKey(pt => pt.UserId);

1
在第一个modelBuilder.Entity中,应该改成".WithMany(p => p.Users)"而不是".WithMany(p => p.Contacts)"吗? - Carlos
@CarlosAdrián - 我认为不是这样的。因为它引用的是同一张表格。它仍然是一个拥有多个联系人的用户。联系人仍然是一个用户。 - smoksnes
3
这个解决方案对我无效。相反,我找到了一个类似问题的答案,它解决了我的多对多自引用问题:https://dev59.com/01UM5IYBdhLWcg3wKNyB#49219124 - Jpsy
@Jpsy 是的,你说得对。原来的答案是不正确的。原来的答案只适用于两种不同类型之间的多对多关系,而不适用于同一类型。我已经修改了答案。现在它可以适用于同一类型。 - TanvirArjel
1
@TanvirArjel:抱歉,我还没有看到你的编辑。你是否正确保存了更改?目前这个答案的最后编辑时间是2017年2月25日。 - Jpsy
@Jpsy smoksnes没有批准我的修改,我已经将其作为单独的答案发布了。请检查一下。 - TanvirArjel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接