Wie blättern Sie in einer Sammlung in LINQ, wenn Sie ein startIndex
und ein haben count
?
84
Vor einigen Monaten schrieb ich einen Blog-Beitrag über Fluent Interfaces und LINQ, in dem eine Erweiterungsmethode für IQueryable<T>
und eine andere Klasse verwendet wurden, um die folgende natürliche Methode zur Paginierung einer LINQ-Sammlung bereitzustellen.
var query = from i in ideas
select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);
Sie können den Code von der MSDN-Codegalerieseite abrufen: Pipelines, Filter, Fluent API und LINQ to SQL .
Es ist sehr einfach mit den Skip
und Take
Erweiterungsmethoden.
var query = from i in ideas
select i;
var paggedCollection = query.Skip(startIndex).Take(count);
Ich habe das etwas anders gelöst als die anderen, da ich meinen eigenen Paginator mit einem Repeater herstellen musste. Also habe ich zuerst eine Sammlung von Seitenzahlen für die Sammlung von Gegenständen erstellt, die ich habe:
Auf diese Weise könnte ich die Objektsammlung leicht in eine Sammlung von "Seiten" unterteilen. Eine Seite ist in diesem Fall nur eine Sammlung von Elementen (
IEnumerable<Item>
). So können Sie es mitSkip
undTake
zusammen mit der Auswahl des Index aus dempageRange
oben erstellten tun :Natürlich müssen Sie jede Seite als zusätzliche Sammlung behandeln, aber wenn Sie beispielsweise Repeater verschachteln, ist dies tatsächlich einfach zu handhaben.
Die einzeilige TLDR- Version wäre folgende:
Welches kann wie folgt verwendet werden:
quelle
Diese Frage ist etwas alt, aber ich wollte meinen Paging-Algorithmus veröffentlichen, der die gesamte Prozedur (einschließlich Benutzerinteraktion) zeigt.
Wenn Sie jedoch nach Leistung streben und im Produktionscode alle nach Leistung streben, sollten Sie das Laging von LINQ nicht wie oben gezeigt verwenden, sondern den zugrunde liegenden
IEnumerator
Wert, um das Paging selbst zu implementieren. Tatsächlich ist es so einfach wie der oben gezeigte LINQ-Algorithmus, aber leistungsfähiger:Erläuterung: Der Nachteil einer
Skip()
mehrfachen "kaskadierenden Verwendung" besteht darin, dass der "Zeiger" der Iteration, in der er zuletzt übersprungen wurde, nicht wirklich gespeichert wird. - Stattdessen wird die ursprüngliche Sequenz mit Sprungaufrufen von vorne geladen, was dazu führt, dass die bereits "verbrauchten" Seiten immer wieder "verbraucht" werden. - Sie können dies selbst beweisen, wenn Sie die Sequenzideas
so erstellen , dass sie Nebenwirkungen hervorruft. -> Selbst wenn Sie 10-20 und 20-30 übersprungen haben und 40+ verarbeiten möchten, werden alle Nebenwirkungen von 10-30 erneut ausgeführt, bevor Sie mit der Iteration von 40+ beginnen. Die Variante, dieIEnumerable
die Benutzeroberfläche direkt verwendet, merkt sich stattdessen die Position am Ende der letzten logischen Seite, sodass kein explizites Überspringen erforderlich ist und Nebenwirkungen nicht wiederholt werden.quelle