Wie würden Sie Paging in einer LINQ-Abfrage implementieren? Eigentlich wäre ich vorerst zufrieden, wenn die SQL-TOP-Funktion nachgeahmt werden könnte. Ich bin mir jedoch sicher, dass der Bedarf an vollständiger Paging-Unterstützung ohnehin schon früher auftritt.
var queryResult = from o in objects
where ...
select new
{
A = o.a,
B = o.b
}
????????? TOP 10????????
Verwenden
Skip
undTake
ist definitiv der richtige Weg. Wenn ich dies implementieren würde, würde ich wahrscheinlich meine eigene Erweiterungsmethode schreiben, um Paging zu handhaben (um den Code besser lesbar zu machen). Die Implementierung kann natürlich verwendenSkip
undTake
:Die Klasse definiert zwei Erweiterungsmethoden - eine für
IEnumerable
und eine fürIQueryable
, was bedeutet, dass Sie sie sowohl mit LINQ to Objects als auch mit LINQ to SQL verwenden können (beim Schreiben einer Datenbankabfrage wählt der Compiler dieIQueryable
Version aus).Abhängig von Ihren Paging-Anforderungen können Sie auch zusätzliches Verhalten hinzufügen (z. B. um mit Negativ
pageSize
oderpage
Wert umzugehen). Hier ist ein Beispiel, wie Sie diese Erweiterungsmethode in Ihrer Abfrage verwenden würden:quelle
IEnumerable
eher die Schnittstelle alsIQueryable
diese verwendet wird, wird die gesamte Datenbanktabelle abgerufen, was einen großen Leistungseinbruch darstellt.IQueryable
, damit es auch mit Datenbankabfragen funktioniert (ich habe die Antwort bearbeitet und hinzugefügt). Es ist ein bisschen bedauerlich, dass Sie den Code nicht vollständig generisch schreiben können (in Haskell wäre dies mit Typklassen möglich). In der ursprünglichen Frage wurde LINQ to Objects erwähnt, daher habe ich nur eine Überladung geschrieben.Hier ist mein performanter Ansatz zum Paging bei der Verwendung von LINQ für Objekte:
Dies kann dann wie folgt verwendet werden:
Nichts von diesem Müll
Skip
undTake
das wird sehr ineffizient sein, wenn Sie an mehreren Seiten interessiert sind.quelle
Paginate
zu entfernennoun
vsverb
Mehrdeutigkeit.quelle
Ich weiß nicht, ob dies jemandem helfen wird, aber ich fand es nützlich für meine Zwecke:
Um dies zu verwenden, hätten Sie eine Linq-Abfrage und würden das Ergebnis zusammen mit der Seitengröße an eine foreach-Schleife übergeben:
Dies wird also über jeden Autor iterieren und jeweils 100 Autoren abrufen.
quelle
BEARBEITEN - Überspringen (0) entfernt, da dies nicht erforderlich ist
quelle
Take
10,Skip
0 nimmt die ersten 10 Elemente.Skip
0 ist sinnlos und sollte niemals gemacht werden. Und die ReihenfolgeTake
und dieSkip
Angelegenheiten -Skip
10,Take
10 nehmen die Elemente 10-20 an;Take
10,Skip
10 gibt keine Elemente zurück.Batchsize wird offensichtlich eine ganze Zahl sein. Dies nutzt die Tatsache aus, dass Ganzzahlen einfach Dezimalstellen löschen.
Ich scherze nur halb mit dieser Antwort, aber sie wird tun, was Sie wollen, und weil sie aufgeschoben wird, werden Sie keine große Leistungsstrafe erleiden, wenn Sie dies tun
Diese Lösung ist nicht für LinqToEntities, ich weiß nicht einmal, ob sie daraus eine gute Abfrage machen könnte.
quelle
Ähnlich wie bei Lukazoid habe ich eine Erweiterung für IQueryable erstellt.
Es ist nützlich, wenn Skip oder Take nicht unterstützt werden.
quelle
Ich benutze diese Erweiterungsmethode:
quelle
das habe ich getan Normalerweise beginnen Sie bei 1, aber in IList beginnen Sie mit 0. Wenn Sie also 152 Zeilen haben, bedeutet dies, dass Sie 8 Seiten haben, in IList jedoch nur 7. Hüpfen Sie, dies kann Ihnen die Sache klar machen
quelle
quelle
Es gibt zwei Hauptoptionen:
.NET> = 4.0 Dynamic LINQ :
var people = people.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
Sie können es auch von NuGet erhalten .
.NET <4.0- Erweiterungsmethoden :
quelle