Können wir die Reihenfolge der LINQ-Ausdrücke mit Skip (), Take () und OrderBy () steuern?
Ich verwende LINQ to Entities, um ausgelagerte Ergebnisse anzuzeigen. Aber ich habe Probleme mit der Kombination vonSkip()
, Take()
undOrderBy()
Anrufe.
Alles funktioniert gut, außer dasOrderBy()
wird zu spät vergeben. Es wird ausgeführt, nachdem die Ergebnismenge von gekürzt wurdeSkip()
undTake()
.
Auf jeder Ergebnisseite sind die Elemente in der richtigen Reihenfolge angeordnet. Die Bestellung erfolgt jedoch auf einer Seite mit einer Handvoll Daten, anstatt den gesamten Satz zu bestellen und diese Datensätze dann mit zu begrenzenSkip()
undTake()
.
Wie lege ich bei diesen Anweisungen den Vorrang fest?
Mein Beispiel (vereinfacht)var query = ctx.EntitySet.Where(/* filter */).OrderByDescending(e => e.ChangedDate);
int total = query.Count();
var result = query.Skip(n).Take(x).ToList();
Eine mögliche (aber eine schlechte) LösungEine mögliche Lösung besteht darin, den Clustered-Index auf die Reihenfolge nach Spalten anzuwenden. Diese Spalte ändert sich jedoch häufig, wodurch die Datenbankleistung bei Einfügungen und Aktualisierungen beeinträchtigt wird. Und das will ich wirklich nicht.
BEARBEITENich rannteToTraceString()
auf meine Abfrage, wo wir tatsächlich sehen können, wann order by auf die Ergebnismenge angewendet wird. Leider am Ende. :(
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