101 votes

Pagination avec LINQ pour les objets

Comment voulez-vous mettre en œuvre la pagination dans une requête LINQ? En fait pour le moment, je serais satisfait si le sql fonction SUPÉRIEURE pourrait être imité. Cependant, je suis sûr que la nécessité de la pagination de soutien vient tôt ou tard de toute façon.

var queryResult = from o in objects
                  where ...
                  select new
                      {
                         A = o.a,
                         B = o.b
                      }
                   ????????? TOP 10????????

256voto

David Pfeffer Points 12792

Vous êtes à la recherche pour l' Skip et Take les méthodes d'extension. Skip se déplace au-delà des N premiers éléments de la suite, en retournant le reste; Take renvoie les N premiers éléments de la suite, l'abandon de toute les autres éléments.

Voir MSDN pour plus d'informations sur la façon d'utiliser ces méthodes: http://msdn.microsoft.com/en-us/library/bb386988.aspx

Par exemple:

int numberOfObjectsPerPage = 10;
var queryResultPage = queryResult
  .Skip(numberOfObjectsPerPage * pageNumber)
  .Take(numberOfObjectsPerPage);

57voto

Tomas Petricek Points 118959

À l'aide de Skip et Take est certainement le chemin à parcourir. Si j'étais la mise en œuvre de la présente, je serais probablement écrire 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 utiliser Skip et Take:

static class PagingUtils {
  IEnumerable<T> Page(this IEnumerable<T> en, int pageSize, int page) {
    return en.Skip(page * pageSize).Take(pageSize);
  }
  IQueryable<T> Page(this IQueryable<T> en, int pageSize, int page) {
    return en.Skip(page * pageSize).Take(pageSize);
  }
}

La classe définit deux méthodes d'extension - l'une pour l' IEnumerable et l'autre pour IQueryable, ce qui signifie que vous pouvez l'utiliser avec les deux LINQ to Objects et LINQ to SQL (lors de l'écriture de requête de base de données, le compilateur va chercher l' IQueryable version).

En fonction de votre pagination conditions, vous pouvez aussi ajouter du comportement (par exemple pour gérer les négatifs pageSize ou page de la valeur). Voici un exemple de comment vous pouvez utiliser cette méthode d'extension dans votre requête:

var q = (from p in products
         where p.Show == true
         select new { p.Name }).Page(10, pageIndex);

42voto

Lukazoid Points 6577

Voici mon performant approche à la pagination lors de l'utilisation de LINQ to objects:

public static IEnumerable<IEnumerable<T>> Page<T>(this IEnumerable<T> source, int pageSize)
{
    Contract.Requires(source != null);
    Contract.Requires(pageSize > 0);
    Contract.Ensures(Contract.Result<IEnumerable<IEnumerable<T>>>() != null);

    using (var enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            var currentPage = new List<T>(pageSize)
            {
                enumerator.Current
            };

            while (currentPage.Count < pageSize && enumerator.MoveNext())
            {
                currentPage.Add(enumerator.Current);
            }
            yield return new ReadOnlyCollection<T>(currentPage);
        }
    }
}

Cela peut ensuite être utilisé comme suit:

var items = Enumerable.Range(0, 12);

foreach(var page in items.Page(3))
{
    // Do something with each page
    foreach(var item in page)
    {
        // Do something with the item in the current page       
    }
}

Aucune de ces ordures Skip et Take qui sera très inefficace si vous êtes intéressé dans plusieurs pages.

10voto

Noel Points 438
   ( for o in objects
    where ...
    select new
   {
     A=o.a,
     B=o.b
   })
.Skip((page-1)*pageSize)
.Take(pageSize)

5voto

Jack Marchetti Points 8912

EDIT: Supprimé l'Ignorer(0), il n'est pas nécessaire

var queryResult = (from o in objects where ...
                      select new
                      {
                          A = o.a,
                          B = o.b
                      }
                  ).Take(10);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X