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

Posted

技术标签:

【中文标题】Entity Framework Core:与同一实体的多对多关系【英文标题】:Entity Framework Core: many-to-many relationship with same entity 【发布时间】:2016-09-29 13:33:57 【问题描述】:

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

public class User : DomainModel

    public virtual IList<User> Contacts  get; protected set; 
    //irrelevant code omitted

当我尝试使用 fluent API 来映射这种多对多关系时,它给我带来了一些麻烦。显然,当我在user.Contacts 属性上使用HasMany() 时,它没有WithMany() 方法可以调用下一个。 Visual Studio 的智能感知仅显示 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 

那么为什么会这样呢?在映射这种多对多关系时我做错了什么吗?

【问题讨论】:

你可以看看这个:ef.readthedocs.io/en/latest/modeling/… 【参考方案1】:

那么为什么会这样呢?我做错了什么来映射这个 多对多关系?

不,你没有做错任何事。 It's just not supported。当前状态here。

没有实体类来表示的多对多关系 尚不支持连接表。但是,您可以代表一个 通过包含连接的实体类来实现多对多关系 表和映射两个单独的一对多关系。

使用 EF-Core,您应该为映射表创建实体。如UserContacts。 docs 中的完整示例,如 cmets 中所述。我还没有实际测试过下面的代码,但它应该看起来像这样:

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

【讨论】:

在第一个modelBulder.Entity中,应该是“.WithMany(p => p.Users)”而不是“.WithMany(p => p.Contacts)”吗? @CarlosAdrián - 我不这么认为。因为它是对同一张表的引用。它仍然是一个有多个联系人的用户。联系人仍然是用户。 这个解决方案对我不起作用。相反,我找到了一个类似问题的以下答案,为我解决了多对多自引用问题:***.com/a/49219124/430742 @Jpsy 是的,你是对的。现有答案不正确。现有答案仅适用于两种不同类型之间的多对多,而不适用于同一类型。我已经修改了答案。现在它将适用于相同的类型。 @TanvirArjel:抱歉,我还没有看到你的编辑。您是否正确保存了更改?目前,此答案的最后一次编辑是从 2017 年 2 月 25 日开始。

以上是关于Entity Framework Core:与同一实体的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

使用 Entity Framework Core 的 Blazor 并发问题

与 Entity Framework Core 2.0 的一对零关系

如何使用 Entity Framework Core 在一种方法中保存两次更改

Entity Framework Core 中的日志记录与拦截器

Entity Framework Core中的日志记录与拦截器

Entity Framework Core 中的日志记录与拦截器