问题是,您的数据库还不够规范化。
我看到用户可以创建Posts。他们也可以在Post 上Comment 和Like cmets。
由于Comment 是Comment about a Post,因此Comment 上的Like 自动成为评论所针对的Post 上的Like
换句话说:如果有人为帖子 (10) 创建了评论 (4),那么为评论 (4) 和帖子 (20) 创建一个赞是荒谬的。评论(4)与帖子(20)无关!
每个赞都是由一个用户针对一个评论创建的。用户创建了零个或多个赞(一对多),并且评论被赞了零次或多次(也是一对多)
所以你有以下动作序列:
- 用户 1 创建帖子 10:帖子 10 具有外键 CreateByUserId 1
- 用户 2 创建关于帖子 10 的评论 20。评论 20 具有 CommentedByUserId 2 和 PostId 20
- 用户 3 赞了评论 20。赞 30 有 LikedByUserId 3 和 CommentId 20
这对于实体框架来说已经足够标准化了。为了使关系更清晰,我稍微更改了外键。
class User
{
public int Id {get; set;}
...
// Every User creates zero or more Posts (one-to-many)
public virtual ICollection<Post> Posts {get; set;}
// Every User creates zero or more Comments (one-to-many)
public virtual ICollection<Comment> Comments {get; set;}
// Every User creates zero or more Likes (one-to-many)
public virtual ICollection<Like> Likes {get; set;}
}
class Post
{
public int Id {get; set;}
...
// Every Post is posted by exactly one User, using foreign key
public int PostedByUserId {get; set;}
public User User {get; set;}
// Every Post has zero or more Comments (one-to-many)
public virtual ICollection<Comment> Comments {get; set;}
}
和类评论和喜欢:
class Comment
{
public int Id {get; set;}
...
// Every Comment is posted by exactly one User, using foreign key
public int CommentedByUserId {get; set;}
public virtual User User {get; set;}
// Every Comment is about exactly one Post, using foreign key
public int PostId {get; set;}
public virtual Post Post {get; set;}
// Every Comment has zero or more Likes (one-to-many)
public virtual ICollection<Like> Likes {get; set;}
}
class Like
{
public int Id {get; set;}
...
// Every Like is created by exactly one User, using foreign key
public int LikedByUserId {get; set;}
public virtual User User {get; set;}
// Every Like is about exactly one Comment, using foreign key
public int CommentId {get; set;}
public virtual Comment Comment {get; set;}
}
因为我的外键偏离了约定,我需要使用 fluent API 通知实体框架这些外键:
帖子对用户有外键:
modelBuilder.Entity<Post>()
.HasRequired(post => post.User)
.WithMany(user => user.Posts)
.HasForeignKey(post => post.CreatedByUserId);
评论有用户和帖子的外键:
var commentEntity = modelBuilder.Entity<Comment>();
commentEntity.HasRequired(comment => comment.User)
.WithMany(user => user.Comments)
.HasForeignKey(comment => comment.CommentedByUserId);
commentEntity.HasRequired(comment => comment.Post)
.WithMany(post => post.Comments)
.HasForeignKey(comment => comment.PostId);
Like 对 User 和 Comment 有外键:
var likeEntity = modelBuilder.Entity<Like>();
likeEntity.HasRequired(like => like.User)
.WithMany(user => user.Likes)
.HasForeignKey(like => like.LikedByUserId);
likeEntity.HasRequired(like => like.Comment)
.WithMany(comment => comment.Likes)
.HasForeignKey(like => like.CommentId);
如果将来您想让用户喜欢帖子而不是评论,或者可能喜欢用户,则关系将非常相似。首先为用户提供正确的virtual ICollection<...>(每个用户都喜欢零个或多个...),您将自动知道将外键放在哪里