EF Core — отношения «многие ко многим» в классе

Отношения пользователя и друга

я нахожу ответ

Ядро Entity Framework: отношения "многие ко многим" с одинаковыми сущность и попробуйте так.

Сущности:

public class User
{
    public int UserId { get; set; }

    public virtual ICollection<Friend> Friends { get; set; }
}

public class Friend
{
    public int MainUserId { get; set; }

    public User ManUser { get; set; }

    public int FriendUserId { get; set; }

    public User FriendUser { get; set; }
}

Свободный API:

modelBuilder.Entity<Friend>()
    .HasKey(f => new { f.MainUserId, f.FriendUserId });

modelBuilder.Entity<Friend>()
    .HasOne(f => f.ManUser)
    .WithMany(mu => mu.Friends)
    .HasForeignKey(f => f.MainUserId);

modelBuilder.Entity<Friend>()
    .HasOne(f => f.FriendUser)
    .WithMany(mu => mu.Friends)
    .HasForeignKey(f => f.FriendUserId);

Когда я добавляю миграцию, появляется сообщение об ошибке

Невозможно создать связь между «User.Friends» и «Friend.FriendUser», поскольку связь между «User.Friends» и «Friend.ManUser» уже существует. Свойства навигации могут участвовать только в одном отношении.

Что я должен делать? Или мне следует создать Entity FriendEntity:User?


person Lin Baby    schedule 12.03.2017    source источник


Ответы (2)


Проблема в том, что у вас не может быть одной коллекции для поддержки обеих ассоциаций «один ко многим». Friend имеет два внешних ключа, которым нужен обратный конец в объекте, на который они ссылаются. Поэтому добавьте еще одну коллекцию в качестве обратного конца MainUser:

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<Friend> MainUserFriends { get; set; }
    public virtual ICollection<Friend> Friends { get; set; }
}

И отображение:

modelBuilder.Entity<Friend>()
    .HasKey(f => new { f.MainUserId, f.FriendUserId });

modelBuilder.Entity<Friend>()
    .HasOne(f => f.MainUser)
    .WithMany(mu => mu.MainUserFriends)
    .HasForeignKey(f => f.MainUserId).OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<Friend>()
    .HasOne(f => f.FriendUser)
    .WithMany(mu => mu.Friends)
    .HasForeignKey(f => f.FriendUserId);

Одно (или оба) отношения должны быть без каскадного удаления, чтобы предотвратить множественные каскадные пути.

person Gert Arnold    schedule 12.03.2017

Второй сбор не обязателен. Вам нужно только оставить de .WithMany() пустым, как это:

modelBuilder.Entity<Friend>()
    .HasOne(f => f.MainUser)
    .WithMany()
    .HasForeignKey(f => f.MainUserId);

modelBuilder.Entity<Friend>()
    .HasOne(f => f.FriendUser)
    .WithMany()
    .HasForeignKey(f => f.FriendUserId);

посмотрите на это: https://github.com/aspnet/EntityFramework/issues/6052

person Alejo Ferrand    schedule 15.06.2017
comment
Спасибо, выход из WithMany, похоже, решил проблему для меня. - person Gary Holland; 25.08.2017
comment
Попытка сделать это оставила меня с дополнительной ненужной связью внешнего ключа в БД (у меня было три вместо двух. Один из которых был избыточным, но просто назван по-другому). Чтобы это исправить, я повторно добавил один из параметров в вызов WithMany() следующим образом: (f => f.FriendUserId); - person BernardV; 10.11.2017