EF-core Howto, чтобы установить много-много отношений с «собой» - PullRequest
0 голосов
/ 16 октября 2019

Дело: Член команды - это любой, кто работает в больнице. Члены команды (врачи) могут иметь других членов команды в качестве своих помощников (медсестры или другого доктора), или члены команды могут быть помощниками другого члена команды.

Классы

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

При создании db-миграции я получаю следующее

ОШИБКА: Невозможно создать связь между «Teammember.AssistantLinks» и «AssistantLink.Assistant», поскольку уже существует связь между «Teammember.AssistantLinks» и «AssistantLink.CareProvider». Свойства навигации могут участвовать только в одном отношении.

Любые предложения, как настроить это правильно?

1 Ответ

1 голос
/ 16 октября 2019

Невозможно иметь только одну коллекцию с отношениями. Вам нужно два - один со ссылками помощника, член команды равен 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); 
    }
...