EF核心如何与“自己”建立多对多关系

时间:2019-10-16 07:32:24

标签: entity-framework-core ef-code-first asp.net-core-2.0

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

课程

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

在数据库环境中,我尝试通过以下方式建立这种关系:

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

创建数据库迁移时,我得到以下信息

  

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

任何建议如何正确设置此方法?

1 个答案:

答案 0 :(得分:1)

不可能只有一个具有关系的集合。您需要两个-一个是团队成员等于CareProvider的助手链接,另一个是团队成员等于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); 
    }