c# - EF Core - 带有嵌套评论的讨论板
问题描述
我正在尝试制作一个类似于 Reddit 的讨论板,其中一个帖子可以有多个评论,每个评论可以有多个评论,每个评论可以有多个评论,等等。
我将如何编写查询以返回包含其所有评论的特定帖子,以及所有评论的评论以及所有这些评论的评论等?我考虑过使用 .ThenInclude() 但这是不可能的,因为我不知道提前有多少嵌套评论。
这是我目前拥有的,但它只检索对帖子的直接回复,没有任何嵌套评论:
selected = await context.Posts
.Include(p => p.Author)
.Include(p => p.SavedBy)
.Include(p => p.HiddenBy)
.Include(p => p.UpvotedBy)
.Include(p => p.DownvotedBy)
.Include(p => p.Replies.Where(c => !c.HiddenBy.Contains(user)))
.ThenInclude(c => c.Author)
.Include(p => p.Replies)
.ThenInclude(c => c.SavedBy)
.Include(p => p.Replies)
.ThenInclude(c => c.HiddenBy)
.Include(p => p.Replies)
.ThenInclude(c => c.UpvotedBy)
.Include(p => p.Replies)
.ThenInclude(c => c.DownvotedBy)
.SingleAsync(p => p.Id == id);
模型:
public abstract class Entry
{
public Entry()
{
Replies = new List<Comment>();
SavedBy = new List<ApplicationUser>();
HiddenBy = new List<ApplicationUser>();
UpvotedBy = new List<ApplicationUser>();
DownvotedBy = new List<ApplicationUser>();
}
public int Id { get; set; }
public string Content { get; set; }
public DateTime DateCreated { get; set; }
public int Upvotes { get; set; }
public int Downvotes { get; set; }
public int VoteScore { get; set; }
public ApplicationUser Author { get; set; }
public ICollection<Comment> Replies { get; set; }
public ICollection<ApplicationUser> SavedBy { get; set; }
public ICollection<ApplicationUser> HiddenBy { get; set; }
public ICollection<ApplicationUser> UpvotedBy { get; set; }
public ICollection<ApplicationUser> DownvotedBy { get; set; }
}
public class Post : Entry
{
public string Title { get; set; }
}
public class Comment : Entry
{
public Entry RepliedTo { get; set; }
public Post Post { get; set; }
}
数据库上下文:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Entry> Entries { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<Comment> Comments { get; set; }
}
解决方案
想一想查询在 SQL 而不是 C#/LINQ 中的外观。由于关系将是递归的,因此您需要为需要预取的许多层显式定义连接。这会让您丢失任何层之外的数据。或者,您可以使用由存储过程绑定的游标。不。相反,评论可以有一个指向其父评论的指针,但也可以有一个指向 MOST 父实体(原始帖子)的外键。然后,当您获得帖子的所有评论时,您可以将所有评论作为平面数组检索,然后在 c#(SQL 之外)中构建树。这应该性能更高。
推荐阅读
- git - 使用 PowerShell 远程处理在 Windows Server 上安装 git
- jhipster - 添加新实体
- bbc-microbit - 从命令行生成 micropython + python 代码 `.hex` 文件
- php - 使用 php 使引导导航栏动态化
- database - MongoDB查询基于多个参数搜索用户
- java - 为什么 Collectors.toMap 需要非空值
- python - Gurobi中的分段线性函数,理解示例
- html - 关于定位 HTML
- javascript - Three.js – 将纹理应用于 Collada 网格会产生意想不到的结果
- html - 纯CSS更改滚动固定导航栏的背景颜色?