2010-11-25 29 views
4

J'ai implémenté une routine de pagination en utilisant skip and take. Cela fonctionne très bien, mais j'ai besoin du nombre total d'enregistrements dans la table avant d'appeler Take and Skip.LINQ: Technique de pagination, utilisation de la prise et du saut, mais nécessite également des enregistrements complets - comment l'implémenter?

Je sais que je peux soumettre 2 requêtes séparées.

  1. Get Count
  2. Sauter et Take

Mais je préférerais ne pas émettre 2 appels à LINQ.

Comment puis-je le renvoyer dans la même requête (par exemple en utilisant une instruction select imbriquée)?

Auparavant, j'ai utilisé une technique de pagination dans une procédure stockée. J'ai renvoyé les articles en utilisant une table temporaire, et j'ai passé le compte à un paramètre de sortie.

Répondre

8

Je suis désolé, mais vous ne pouvez pas. Au moins, pas d'une manière jolie.

Vous pouvez le faire d'une manière unpretty, mais je ne pense pas que vous comme ça:

Vous voyez? Pas joli du tout.

+4

Il s'agit toujours de deux requêtes sur la base de données. Il ressemble seulement à une requête si vous plissez assez fort à la requête LINQ. ;-) – Enigmativity

+3

En fait, ce code n'entraîne en fait aucune requête de base de données. Seulement si vous itérez sur 'pagedQuery', la base de données sera appelée. Cela dépend également du fournisseur LINQ, mais un bon fournisseur l'exécutera comme une seule requête databsae. Certains fournisseurs peuvent exécuter des requêtes N + 1. En outre, l'exécution de deux requêtes distinctes (un nombre et une requête de résultats) aura probablement de meilleures performances que cette chose. Comme je l'ai dit, ce n'est pas joli. – Steven

+0

remercie Steven! bien peut-être que ce n'est pas joli mais je l'aime bien :-) .. Pensez-vous que linq2sql exécuterait 1 requête ou utiliserait 2? Ou pensez-vous que ce serait un vrai problème de performance de faire juste 2 requêtes? c'est-à-dire obtenir mon compte et stocker en variable et puis nouvelle requête pour faire ma prise et sauter – Martin

0

Il n'y a aucune raison de faire deux requêtes séparées ou même une procédure stockée. Utilisez un let binding pour noter une sous-requête lorsque vous avez terminé, vous pouvez avoir un type anon qui contient à la fois votre élément sélectionné ainsi que votre nombre total. Une seule requête à la base de données, 1 expression linq et votre fait. Pour obtenir les valeurs, il s'agirait de jobQuery.Select (x => x.item) ou de jobQuery.FirstOrDefault(). Count

Laissez les expressions sont une chose incroyable.

var jobQuery = (
       from job in jc.Jobs 
       let jobCount = (
            from j in jc.Jobs 
            where j.CustomerNumber.Equals(CustomerNumber) 
            select 
             j 
           ).Count() 
       where job.CustomerNumber.Equals(CustomerNumber) 
       select 
       new 
       { 
        item = job.OrderBy(x => x.FieldName).Skip(0).Take(100), 
        Count = jobCount 
       } 
      ); 
+0

inutile lorsque vous ajoutez prendre/skip –

+0

Vous faites le saut/prendre item = job.Skip (#). Take (#). Down vote pour une réponse valide qui peut même encore résoudre votre situation est déplacée. – VulgarBinary

+0

La réponse devrait refléter avec skip/take comme op. Il ne répond pas à la question op. -1 –