Podemos controlar a ordem da expressão LINQ com Skip (), Take () e OrderBy ()
Estou usando o LINQ to Entities para exibir resultados paginados. Mas estou tendo problemas com a combinação deSkip()
, Take()
eOrderBy()
chamadas.
Tudo funciona bem, exceto queOrderBy()
é atribuído tarde demais. É executado após o conjunto de resultados ser reduzido porSkip()
eTake()
.
Portanto, cada página de resultados tem itens em ordem. Porém, o pedido é feito em uma página cheia de dados, em vez de em todo o conjunto e depois na limitação desses registros comSkip()
eTake()
.
Como faço para definir precedência com essas instruções?
Meu exemplo (simplificado)var query = ctx.EntitySet.Where(/* filter */).OrderByDescending(e => e.ChangedDate);
int total = query.Count();
var result = query.Skip(n).Take(x).ToList();
Uma solução possível (mas ruim)Uma solução possível seria aplicar o índice clusterizado para ordenar por coluna, mas essa coluna muda frequentemente, o que diminui o desempenho do banco de dados em inserções e atualizações. E eu realmente não quero fazer isso.
EDITAREu corriToTraceString()
na minha consulta, onde podemos realmente ver quando a ordem de é aplicada ao conjunto de resultados. Infelizmente no final. :(
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