【发布时间】:2011-02-15 17:59:01
【问题描述】:
我在一个论坛网站上使用实体框架,并且有两个带有问题的查询示例。
查询 #1) 该查询应该获取论坛中所有主题的主题计数。它是否在 SQL 中执行计数,以便我只得到一个数字?还是将所有主题拉入内存,然后统计集合中的主题?
return DBContext.Topics
.Where(x => !x.ModsOnly)
.Where(x => !x.Board.ModsOnly)
.Where(x => !x.Board.Hidden)
.Count();
查询#2)这个查询应该获取所有主题,按最后回复日期(如果没有回复,则按主题日期)对它们进行排序。然后它计算结果,并对结果进行分页。这个查询中有多少是在数据库中执行的?这个查询需要 FOREVER,所以我认为它会在某个时间点将所有主题拉入内存,可能在分页生效之前。
var query = DBContext.Topics
.Where(x => !x.ModsOnly)
.Where(x => !x.Board.ModsOnly)
.Where(x => !x.Board.Hidden)
.OrderByDescending(x => x.GlobalSticky)
.ThenByDescending(x => x.Replies
.Where(r => !r.ModsOnly)
.Any() ? x.Replies
.Where(r => !r.ModsOnly)
.Max(r => r.PostedDate) : x.PostedDate);
int totalTopics = query.Count();
if (totalTopics > itemsPerPage)
return query.Skip((page - 1) * itemsPerPage).Take(itemsPerPage);
else
return query;
我不是 LINQ 专家,因此不胜感激。我知道这是一个复杂的查询,但如果有人可以花一点时间来解析它并找出我在哪里/如果我在某个地方出错了,那将非常有帮助。
注意:我试图避免在名为“LastReplyDate”的主题中创建一个列并以此为主题排序。出于我的目的,我真的希望通过最后一个回复来完成排序,而不是通过关于主题的任意列,我可能必须在每个添加/删除的回复中进行更新。 但是,如果你们认为没有其他方法可以实现我的目标,我会考虑这条路线。
【问题讨论】:
-
@Chevex 是不是更容易附加 sqlprofiler 来检查查询的性能和行为?
-
@marc 嗯,我不知道我能做到这一点。这是 EF 上下文对象上的方法吗? @rene,我想,介意发布一个答案并举例说明如何做到这一点?
-
公平地说,在 linq-to-SQL(只是 ctx.Log = Console.Out)中更容易 - 使用 EF 的 SQL 分析器工具,或者可能是 Ayende 的分析器
-
@Chevex 如果您使用的是 SQL Server,SSMS 有一个
SQL Server Profiler工具,您可以设置它来跟踪数据库上的 RPC。 -
还有一个选择是使用 LINQPad,它可以理解您的 EF 模型并为您提供 SQL 跟踪。
标签: c# linq entity-framework entity-framework-4 linq-to-entities