Lin Baby Lin Baby - 9 months ago 52
C# Question

EF Core - Many to many relationship on a class

User-Friend relationship



I find an answer

Entity Framework Core: many-to-many relationship with same entity
and try like this.

Entitys:

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


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


When I Add-Migration, the error message is



Cannot create a relationship between 'User.Friends' and 'Friend.FriendUser', because there already is a relationship between 'User.Friends' and 'Friend.ManUser'.
Navigation properties can only participate in a single relationship.

What should I do? Or I should create an Entity FriendEntity:User?

Answer Source

The problem is that you can't have one collection to support both one-to-many associations. Friend has two foreign keys that both need an inverse end in the entity they refer to. So add another collection as inverse end of MainUser:

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

And the mapping:

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

One (or both) of the relationships should be without cascading delete to prevent multiple cascade paths.