我正在使用 LINQ to Entities 来显示分页结果。但是我遇到了Skip()
,Take()
和OrderBy()
调用的组合问题。
一切正常,除了OrderBy()
分配得太晚。Skip()
它在结果集被and削减后执行Take()
。
因此,每一页结果都有按顺序排列的项目。但是排序是在少量数据的页面上完成的,而不是对整个数据集进行排序,然后用Skip()
和限制这些记录Take()
。
如何设置这些语句的优先级?
我的例子(简化)
var query = ctx.EntitySet.Where(/* filter */).OrderByDescending(e => e.ChangedDate);
int total = query.Count();
var result = query.Skip(n).Take(x).ToList();
一种可能(但不好)的解决方案
一种可能的解决方案是将聚集索引应用到按列排序,但该列经常更改,这会降低数据库在插入和更新时的性能。我真的不想那样做。
编辑
我运行ToTraceString()
了我的查询,我们可以实际看到 order by 何时应用于结果集。最后不幸的是。:(
SELECT
-- columns
FROM (SELECT
-- columns
FROM (SELECT -- columns
FROM ( SELECT
-- columns
FROM table1 AS Extent1
WHERE EXISTS (SELECT
-- single constant column
FROM table2 AS Extent2
WHERE (Extent1.ID = Extent2.ID) AND (Extent2.userId = :p__linq__4)
)
) AS Project2
limit 0,10 ) AS Limit1
LEFT OUTER JOIN (SELECT
-- columns
FROM table2 AS Extent3 ) AS Project3 ON Limit1.ID = Project3.ID
UNION ALL
SELECT
-- columns
FROM (SELECT -- columns
FROM ( SELECT
-- columns
FROM table1 AS Extent4
WHERE EXISTS (SELECT
-- single constant column
FROM table2 AS Extent5
WHERE (Extent4.ID = Extent5.ID) AND (Extent5.userId = :p__linq__4)
)
) AS Project6
limit 0,10 ) AS Limit2
INNER JOIN table3 AS Extent6 ON Limit2.ID = Extent6.ID) AS UnionAll1
ORDER BY UnionAll1.ChangedDate DESC, UnionAll1.ID ASC, UnionAll1.C1 ASC