EF-core如何建立与“自身”的many2many关系

Posted

技术标签:

【中文标题】EF-core如何建立与“自身”的many2many关系【英文标题】:EF-core howto set up many2many relationship to 'itself' 【发布时间】:2020-02-12 22:11:49 【问题描述】:

案例:团队成员是在医院工作的任何人。团队成员(医生)可以让其他团队成员作为他们的助手(护士或其他医生),或者团队成员可以是其他团队成员的助手。

public class Teammember 

    Public int Id get; set;
    public ICollection<AssistantLink> AssistantLinks  get;  = new List<AssistantLink>();
    public ICollection<Teammember> Assistants => AssistantLinks.Where(x => x.CareProviderId == Id).Select(x => x.Assistant).ToList();
    public ICollection<Teammember> CareProviders => AssistantLinks.Where(x => x.AssistantId == Id).Select(x => x.CareProvider).ToList();

为了建立这种关系,我创建了一个类“AssistantLink”

   public class AssistantLink : ModelBase
    
        public int CareProviderId  get; set; 
        public Teammember CareProvider  get; set; 
        public int AssistantId  get; set; 
        public Teammember Assistant  get; set; 
    

在 DB 上下文中,我尝试通过以下方式连接这种关系:

    builder.Entity<AssistantLink>().HasKey(x => new  x.CareProviderId, x.AssistantId );
    builder.Entity<AssistantLink>().HasOne(x => x.CareProvider).WithMany("AssistantLinks"); //use string notation because navigation property is private
    builder.Entity<AssistantLink>().HasOne(x => x.Assistant).WithMany("AssistantLinks");

创建 db-migration 时,我得到以下信息

错误:无法在 'Teammember.AssistantLinks' 和 'AssistantLink.Assistant',因为 'Teammember.AssistantLinks' 之间已经存在关系 和“AssistantLink.CareProvider”。导航属性只能 参与单一关系。

有什么建议可以正确设置吗?

【问题讨论】:

EF Core 不支持多对多,因此您不必在中间实体和关系的每一方之间建立 两个 一对多关系.在这里,关系的每一边恰好是同一个实体,因此您需要在该实体上使用两个集合,每一边一个。 【参考方案1】:

不可能只有一个包含关系的集合。您需要两个 - 一个带有 assistantlinks 的团队成员等于 CareProvider,第二个带有 assistantlinks 的团队成员等于 Assistant

型号

public class Teammember

    public int Id  get; set; 
    public ICollection<AssistantLink> Assistants  get; set;  
    public ICollection<AssistantLink> Providers  get; set; 

public class AssistantLink : ModelBase

    public int CareProviderId  get; set; 
    public Teammember CareProvider  get; set; 
    public int AssistantId  get; set; 
    public Teammember Assistant  get; set; 

配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        modelBuilder.Entity<AssistantLink>()
            .HasKey(x => new  x.CareProviderId, x.AssistantId );
        modelBuilder.Entity<AssistantLink>()
            .HasOne(al => al.CareProvider)
            .WithMany(c => c.Providers)
            .HasForeignKey(al => al.CareProviderId)
            .OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<AssistantLink>()
            .HasOne(al => al.Assistant)
            .WithMany(a => a.Assistants)
            .HasForeignKey(al => al.AssistantId)
            .OnDelete(DeleteBehavior.Restrict); 
    

【讨论】:

以上是关于EF-core如何建立与“自身”的many2many关系的主要内容,如果未能解决你的问题,请参考以下文章

EF-Core:表“名称”已经存在 - 尝试更新数据库时

嵌套 tph 继承成员的 ef-core 负载收集属性

我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?

最好的crm客户关系管理软件是啥?

定制APP三步走

离线时无法建立与本地主机的连接