我有一个评论表,如下所示:
Comment{
ID,
Text,
ParentID
}
我正在使用以下查询根据回复数量选择带有分页的热门评论。
var comments = db.Comments
.OrderByDescending(c => db.Comments.Count(r => r.ParentID == c.ID)).Skip(skip).Take(recordsPerPage).ToList();
当我们收到数以千计的评论时,请告诉我处理这种情况的最佳方法吗?
答案 0 :(得分:2)
我会考虑在存储回复计数的Comment
中添加一个额外的列。然后,您可以通过回复计数轻松订购Comments
嵌套查询。
var comments = db.Comments.Skip(skip).Take(recordsPerPage)
.OrderByDescending(c => c.ReplyCount)
.ToList();
答案 1 :(得分:1)
除非您准备在数据库中预先计算它,否则您遇到的问题是您需要执行嵌套查询或执行单次完全获取,然后执行内存中的所有操作。后者是我的选择,直到它被证明太慢。
以下是我最初的做法。
首先,预取:
var allComments = Comments.ToArray();
然后创建一个快速返回注释计数的函数:
var childrenLookup = allComments.ToLookup(x => x.ParentID);
var parentMap = allComments.ToDictionary(x => x.ID, x => x.ParentID);
Func<int, int> getCommentsCount = n =>
{
var r = 0;
if (parentMap.ContainsKey(n))
{
r = childrenLookup[parentMap[n]].Count();
}
return r;
};
现在返回结果几乎是微不足道的:
var comments = allComments
.OrderByDescending(c => getCommentsCount(c.ID))
.Skip(skip)
.Take(recordsPerPage)
.ToList();
(并且,是的,您的排序顺序错误,您可以跳过并进行分页。)
如果您不能在内存中执行此操作,请使用预先计算方法。