Comment implémenteriez-vous la pagination dans une requête LINQ? En fait, pour le moment, je serais satisfait si la fonction SQL TOP pouvait être imitée. Cependant, je suis sûr que le besoin d'une prise en charge complète de la pagination apparaîtra plus tôt de toute façon.
var queryResult = from o in objects
where ...
select new
{
A = o.a,
B = o.b
}
????????? TOP 10????????
Utiliser
Skip
etTake
est définitivement la voie à suivre. Si je mettais en œuvre cela, j'écrirais probablement ma propre méthode d'extension pour gérer la pagination (pour rendre le code plus lisible). La mise en œuvre peut bien sûr utiliserSkip
etTake
:La classe définit deux méthodes d'extension - une pour
IEnumerable
et une pourIQueryable
, ce qui signifie que vous pouvez l'utiliser avec LINQ to Objects et LINQ to SQL (lors de l'écriture de la requête de base de données, le compilateur choisira laIQueryable
version).En fonction de vos besoins de pagination, vous pouvez également ajouter un comportement supplémentaire (par exemple pour gérer une valeur négative
pageSize
ou unepage
valeur). Voici un exemple d'utilisation de cette méthode d'extension dans votre requête:la source
IEnumerable
interface plutôt queIQueryable
cela, la table de base de données entière sera extraite, ce qui sera un impact majeur sur les performances.IQueryable
qu'elle fonctionne également avec les requêtes de base de données (j'ai modifié la réponse et l'ai ajoutée). Il est un peu dommage que vous ne puissiez pas écrire le code de manière totalement générique (en Haskell, cela serait possible avec des classes de types). La question originale mentionnait LINQ to Objects, je n'ai donc écrit qu'une seule surcharge.Voici mon approche performante de la pagination lors de l'utilisation de LINQ vers des objets:
Cela peut ensuite être utilisé comme ceci:
Rien de tout ça
Skip
etTake
qui sera très inefficace si vous êtes intéressé par plusieurs pages.la source
Paginate
pour supprimernoun
contre l'verb
ambiguïté.la source
Je ne sais pas si cela aidera quelqu'un, mais je l'ai trouvé utile pour mes besoins:
Pour utiliser cela, vous auriez une requête linq et passer le résultat avec la taille de la page dans une boucle foreach:
Cela va donc itérer sur chaque auteur en récupérant 100 auteurs à la fois.
la source
EDIT - Suppression du saut (0) car ce n'est pas nécessaire
la source
Take
10,Skip
0 prend les 10 premiers éléments.Skip
0 est inutile et ne devrait jamais être fait. Et l'ordre deTake
etSkip
compte -Skip
10,Take
10 prend les éléments 10-20;Take
10,Skip
10 ne renvoie aucun élément.Batchsize sera évidemment un entier. Cela tire parti du fait que les nombres entiers suppriment simplement les décimales.
Je plaisante à moitié avec cette réponse, mais elle fera ce que vous voulez, et comme elle est différée, vous n'encourrez pas une grosse pénalité de performance si vous le faites
Cette solution n'est pas pour LinqToEntities, je ne sais même pas si cela pourrait en faire une bonne requête.
la source
Semblable à la réponse de Lukazoid, j'ai créé une extension pour IQueryable.
C'est utile si Skip ou Take ne sont pas pris en charge.
la source
J'utilise cette méthode d'extension:
la source
c'est ce que j'ai fait. Normalement, vous commencez à 1 mais dans IList vous commencez par 0. Donc, si vous avez 152 lignes, cela signifie que vous avez 8 pagination, mais dans IList, vous n'avez que 7. hop, cela peut clarifier les choses pour vous
la source
la source
Il existe deux options principales:
.NET> = 4.0 LINQ dynamique :
var people = people.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
Vous pouvez également l'obtenir par NuGet .
Méthodes d'extension .NET <4.0 :
la source