2008-12-08 6 views
13

Est-il possible d'utiliser la fonctionnalité "pagination" dans les requêtes Linq? Disons que j'ai quelques XML comme ceci:Newbie LINQ Question: La pagination dans les requêtes LINQ est-elle possible?

<Root> 
    <BetaSection> 
     <Choices> 
      <SetA> 
       <Choice id="choice1">Choice One</Choice> 
       <Choice id="choice2">Choice Two</Choice> 
       <Choice id="choice3">Choice Three</Choice> 
       . 
       . 
       . 
       <Choice id="choice48">Choice Forty-Eight</Choice> 
       <Choice id="choice49">Choice Forty-Nine</Choice> 
       <Choice id="choice50">Choice Fifty</Choice> 
      </SetA> 
     </Choices> 
    </BetaSection> 
</Root> 

Si je voulais mettre en œuvre la fonctionnalité de recherche de personnes, je serais en mesure de fournir une compensation à une requête LINQ telle que je puisse commencer au 11ème élément et se termine le 20 élément? Si oui, la requête serait-elle différente si les données étaient une liste d'objets au lieu de XML?

+0

La pagination par linq est possible. Je ne sais pas ce que vous essayez d'atteindre.s'il y a d'énormes enregistrements sauvegardés dans le fichier xml et que vous voulez récupérer des données à partir de là par linq avec pagination alors ce n'est pas possible. la plupart du temps, les gens utilisent la classe xml doc pour lire le fichier xml, puis charger les données xml en mémoire. cela ne devrait pas être considéré comme une pagination lorsque des données complètes sont chargées dans la mémoire. linq va juste lire quelques données de la mémoire et revenir ........ mais cela ne peut pas être dit que pagination.pagination signifie que je vais charger seulement quelques données dans la mémoire que je vais montrer ou travailler avec. – Thomas

Répondre

18
var q = from X in Choices.Skip((page-1)*pageSize).Take(pageSize) 
     select X; 

Maintenant, si vous avez besoin d'une clause where, il devient un peu plus délicat:

var q = (from X in Choices 
     where x.SomeField == SomeValue 
     select X).Skip((page-1)*pageSize).Take(pageSize); 
+1

Pour votre deuxième cas, il est probablement plus facile d'utiliser simplement des méthodes d'extension, plutôt que de mélanger la syntaxe du langage: var q = Choices.Where (x => x.SomeField == SomeValue) .Skip ((page - 1) * pageSize). Prendre (pageSize); –

+0

Dans le premier cas, vous pouvez supprimer 'from X in' et' select X'. –

+1

Est-ce que cela fonctionnera lors de l'application orderby? Je veux dire que je m'attends à ce que Linq applique d'abord orderby puis saute et prenne ... – Andry

2
var pagedData = aDataSource.Skip(20).Take(10); 

De cette façon, vous sautez 20 éléments et en prenant la prochaine 10

1

Le "Take" et "Skip" méthodes d'extension prévoient.

myQueryable = myQueryable.Skip(10).Take(10); 
3

Absolument - Skip() et Take() obtenir la pagination, et sont pris en charge par jolie bien tous Fournisseurs LINQ. Dans ce cas, on dirait que vous utilisez LINQ-to-Xml, alors n'hésitez pas à ignorer le bit suivant - mais pour des informations générales: notez que si les données proviennent d'une base de données via une procédure stockée, il est difficile de paginer sur le serveur. Vous pouvez cependant composer (c'est-à-dire, page) "UDF". LINQ-to-SQL prend en charge les fonctions UDF (via [FunctionAttribute]), mais pas Entity Framework. Si vous utilisez des requêtes de base de données générées automatiquement, ce n'est pas un problème.

Notez que XML, vous pouvez aussi faire beaucoup avec XPath - ici en utilisant XmlDocument:

foreach (XmlElement el in doc.SelectNodes(
    "/Root/BetaSection/Choices/SetA/Choice[position() > 11 and position() < 20]")) 
{ 
    Console.WriteLine(el.GetAttribute("id")); 
} 

ou Skip()/Take() (toujours avec XmlDocument):

foreach (var el in doc.SelectNodes(
    "/Root/BetaSection/Choices/SetA/Choice").Cast<XmlElement>() 
    .Skip(10).Take(10)) 
{ 
    Console.WriteLine(el.GetAttribute("id")); 
} 
+0

J'ai vu votre code mais quand nous travaillons avec la classe xmldoc pour charger et lire le fichier xml, d'abord toutes les données sont chargées en mémoire. si toutes les données se chargent en mémoire et en sélectionnent quelques unes avec la fonction skip & take ...... est-ce vraiment considéré comme une pagination? pagination signifie que je vais charger seulement quelques données dans la mémoire que je vais montrer ou travailler avec. – Thomas

1

Oui, il est . Il faudrait obtenir le XML dans un format approprié DataSource puis ce fil sur les forums MSDN devraient fournir les mesures nécessaires pour vous donner la capacité sur la façon de la mettre en œuvre ...

MSDN - LINQ with pagination

3

Prenez un regard sur les méthodes Queryable.Skip et Queryable.Take.

Voir aussi ce extension methods utile pour la pagination,

avec que les méthodes que vous pouvez le faire comme ceci:

List<string> names = new List<string>(); 
names.AddRange(new string[]{"John","Frank","Jeff","George","Bob","Grant", "McLovin"}); 

foreach (string name in names.Page(2, 2)) 
{ 
    Console.WriteLine(name); 
} 
3

James Curran a raison, vous pouvez simplifier cela en créant une méthode d'extension pour la réutilisation plus tard.

Vous pouvez également modifier le code pour vous renvoyer un objet capable de suivre le nombre total d'éléments dans la liste et le nombre de pages à utiliser en fonction des paramètres pageSize et pageIndex.

public static IQueryable<T> ToPageOfList<T>(this IQueryable<T> source, int pageIndex, int pageSize) 
{ 
    return source.Skip(pageIndex * pageSize).Take(pageSize); 
} 

//Example 
var g = (from x in choices select x).ToPageOfList(1, 20);