Comment feuilletez-vous une collection dans LINQ étant donné que vous avez un startIndex
et un count
?
Réponses
Trop de publicités? Il y a quelques mois, j'ai écrit un article sur les interfaces Fluent et LINQ, qui utilisait une méthode d'extension sur IQueryable<T>
et une autre classe pour fournir le moyen naturel suivant de paginer une collection LINQ.
var query = from i in ideas
select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);
Vous pouvez obtenir le code à partir de la page Galerie de codes MSDN: Pipelines, Filtres, API Fluent et LINQ to SQL .
J'ai résolu ce problème un peu différemment de ce que les autres ont comme j'ai eu à faire mon propre paginator, avec un répéteur. J'ai donc d'abord fait une collection de numéros de page pour la collecte des éléments que j'ai:
// assumes that the item collection is "myItems"
int pageCount = (myItems.Count + PageSize - 1) / PageSize;
IEnumerable<int> pageRange = Enumerable.Range(1, pageCount);
// pageRange contains [1, 2, ... , pageCount]
À l'aide de ce que je pouvais facilement la partition de la collection d'éléments dans une collection de "pages". Une page dans ce cas est simplement une collection d'objets (IEnumerable<Item>
). C'est comment vous pouvez le faire en utilisant Skip
et Take
ensemble avec la sélection de l'indice de l' pageRange
créé ci-dessus:
IEnumerable<IEnumerable<Item>> pageRange
.Select((page, index) =>
myItems
.Skip(index*PageSize)
.Take(PageSize));
Bien sûr, vous avez à gérer chaque page est une collection mais par exemple, si vous êtes à la nidification des répéteurs puis c'est facile à gérer.
Le one-liner TLDR version serait celui-ci:
var pages = Enumerable
.Range(0, pageCount)
.Select((index) => myItems.Skip(index*PageSize).Take(PageSize));
Qui peut être utilisé comme ceci:
for (Enumerable<Item> page : pages)
{
// handle page
for (Item item : page)
{
// handle item in page
}
}
Cette question est un peu ancienne, mais je voulais publier mon algorithme de pagination qui montre toute la procédure (y compris l'interaction de l'utilisateur). Il stocke également le " décalage de la dernière page " au lieu de passer de plus en plus d'éléments identiques, ce qui serait quelque peu inefficace.
const int pageSize = 10;
const int count = 100;
const int startIndex = 20;
int took = 0;
bool getNextPage;
var page = ideas.Skip(startIndex);
do
{
Console.WriteLine("Page {0}:", (took / pageSize) + 1);
foreach (var idea in page.Take(pageSize))
{
Console.WriteLine(idea);
}
took += pageSize;
Console.WriteLine("Next page (y/n)?");
char answer = Console.ReadLine().FirstOrDefault();
getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);
if (getNextPage)
{
page = page.Skip(pageSize);
}
}
while (getNextPage && took < count);