.NET EF Core 如何实现自引用多对多关系完成用户好友功能
EF Core 自引用多对多好友关系配置方案
你现有配置的冲突点在于:两个外键都试图绑定到User类的同一个集合导航属性,且配置中引用的UserFriends属性在你的User类中并未定义。不需要新增额外集合属性的配置方式如下:
保留现有UserFriend类的配置方案
你只需将不需要反向导航的关系的WithMany方法设置为无参数即可,无需修改现有User类的结构:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<UserFriend>() .HasKey(i => new { i.UserId, i.FriendId }); // 绑定当前User类中已有的Friends集合,存储当前用户主动添加的好友关联 modelBuilder.Entity<UserFriend>() .HasOne(c => c.User) .WithMany(w => w.Friends) .HasForeignKey(f => f.UserId) .OnDelete(DeleteBehavior.Restrict); // 该关系无需反向集合导航,WithMany留空即可 modelBuilder.Entity<UserFriend>() .HasOne(c => c.Friend) .WithMany() .HasForeignKey(f => f.FriendId) .OnDelete(DeleteBehavior.Restrict); }
配置完成后,你可以直接通过user.Friends获取当前用户主动添加的好友关联记录,如需查询哪些用户添加了当前用户为好友,直接操作UserFriend的DbSet过滤FriendId即可。
如果需要实现双向好友可见,只需在业务逻辑层加好友时同时插入两条反向的UserFriend记录即可。
更简洁的隐式多对多方案(EF Core 5+ 适用,无额外字段时推荐)
如果你的UserFriend不需要存储加好友时间、备注、审核状态等额外字段,可以直接省略UserFriend类的定义,EF Core会自动生成中间表:
- 调整User类的集合属性:
public class User { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } // ... Other properties // 直接存储好友User实体,无需中间实体 public ICollection<User> Friends { get; set; } }
- 对应FluentAPI配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>() .HasMany(u => u.Friends) .WithMany() .UsingEntity<Dictionary<string, object>>( "UserFriends", // 自动生成的中间表名 j => j.HasOne<User>().WithMany().HasForeignKey("FriendId").OnDelete(DeleteBehavior.Restrict), j => j.HasOne<User>().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.Restrict), j => j.HasKey("UserId", "FriendId") ); }
该方案无需手动维护中间实体,直接操作user.Friends即可获取好友的User实体列表,代码更简洁。
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

