c# - EF Core 一对多还是多对多?用户<-->朋友
问题描述
我将在我的项目中实现一个用户朋友模块。
假设我有 2 个简单的类:
public class User
{
int Id { get; set; }
string Name { get; set; }
}
和FriendShip类(用户之间有关系):
public class FriendShip
{
int User1Id { get; set; }
int User2Id { get; set; }
int Status { get; set; }
}
状态类型是Enum
这两个类的逻辑:
- 当第一个用户邀请第二个用户加入他的好友列表时,应该在数据库中创建 2 个对象
user1Id: 1,
user2Id: 2,
Status: 1, (where 1 means 'invited')
user1Id: 2,
user2Id: 1,
Status: 0, (where 0 means 'nonaccepted')
- 当第二个用户接受时,这两个状态将通过值 3 更新(其中表示“友谊”或类似的东西 - 但现在忘记逻辑。
我不知道如何设计数据库。
它将是一对多的,就像一个用户可以与其他用户有很多关系?
私钥必须是 2 个外键:user1, user2
问题是这两个外键进入一个表(用户)
我试过这样的事情:
modelBuilder.Entity<User>()
.HasMany(x => x.UsersFriendships)
.WithOne(x => x.User2)
modelBuilder.Entity<UsersFriendship>()
.HasMany(x => x.Users)
.WithOne(x => x.UsersFriendships)
但这没有意义,我不能做第二个陈述
.WithOne(x => x.userFriendships)
最简单的方法是输入模型生成器:
modelBuilder.Entity<UsersFriendship>()
.HasKey(x => new { x.User1Id, x.User2Id });
用户友谊类:
public class UsersFriendship
{
[ForeignKey("User1Id")]
public User User1 { get; set; }
[ForeignKey("User2Id")]
public User User2 { get; set; }
public int User1Id { get; set; }
public int User2Id { get; set; }
public RelationStatus RelationStatus { get; set; }
}
但从现在开始,我无法从用户实体导航到他的朋友(如User.Friendship
)
当我将导航属性添加到用户类时:
public virtual List<UsersFriendship> UsersFriendships { get; set; }
数据库将四个字段:user1Id、user2Id、status、userId
最新的字段来自用户类(UsersFriendships 字段)<-- 我不想在我的数据库中使用这个字段!
解决方案
您可以在官方文档中找到一个示例:https ://docs.microsoft.com/en-us/ef/core/modeling/relationships#many-to-many 。
我调整了这个例子来反映你的情况:
namespace foo
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<UsersFriendship> UsersFriendships { get; set; }
}
public class Friendship
{
public User User1 { get; set; }
public int User1Id { get; set; }
public User User2 { get; set; }
public int User2Id { get; set; }
public int Status { get; set; }
}
class MyContext : DbContext
{
public DbSet<Friendship> Friendships { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Friendship>()
.HasKey(fs => new { fs.User1, fs.User2, fs.Status });
modelBuilder.Entity<Friendship>()
.HasOne(fs => fs.User1)
.WithMany(u => u.UsersFriendships)
.HasForeignKey(fs => fs.User1);
modelBuilder.Entity<Friendship>()
.HasOne(fs => fs.User2)
.WithMany(u => u.UsersFriendships)
.HasForeignKey(fs => fs.User2);
}
}
最新的字段来自用户类(UsersFriendships 字段)<-- 我不想在我的数据库中使用这个字段!
将其注册为导航属性(请参阅我的代码)时,它将不会存储在 db 中。
在其他情况下,如果出于某种原因您不希望 ef core 将属性存储在 db 中,请使用[NotMapped]
属性 ( namespace System.ComponentModel.DataAnnotations.Schema
) 标记该属性。
推荐阅读
- javascript - 您如何比较用户选择的多项选择答案并返回正确或错误的答案?
- d3.js - 如何将默认值设置为 dc selectMenu
- sql-server - 将 SQL Server 触发器转换为 Oracle 和 master.dbo.sysprocesses - 不重复
- html - 始终在包含潜水的相同位置显示工具提示
- python - cx_Freeze:主脚本中的 Python 错误 - ImportError:DLL 加载失败
- r - Kwic 函数返回“具有 0 行的 kwic 对象”,即使它不应该
- css - 结合引导导航栏和 CSS 网格
- angular - 加载 SVG 文件的内容以在 ngFor 中显示
- stripe-payments - Stripe - 向用户公开费用 ID 是否安全?
- c# - 将 MethodCallExpression 附加到属性/参数