ページングされた結果を表示するために 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();
1つの可能な(しかし悪い)解決策
考えられる解決策の 1 つは、クラスター化インデックスを適用して列ごとに並べ替えることですが、この列は頻繁に変更されるため、挿入および更新時にデータベースのパフォーマンスが低下します。そして、私は本当にそれをしたくありません。
編集
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