¿Cómo hace una página a través de una colección en LINQ dado que tiene un startIndex
y un count
?Paginación de una colección con LINQ
Respuesta
Hace unos meses escribí un post sobre Fluent interfaces y LINQ, que utiliza un método de extensión en IQueryable<T>
y otra clase para proporcionar la siguiente forma natural de paginar una colección de LINQ.
var query = from i in ideas
select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);
que pueda obtener el código de la Galería de código MSDN Página: Pipelines, Filters, Fluent API and LINQ to SQL.
Es muy simple con los métodos de extensión Skip
y Take
.
var query = from i in ideas
select i;
var paggedCollection = query.Skip(startIndex).Take(count);
Esta pregunta es algo antigua, pero quería publicar mi algoritmo de paginación que muestra todo el procedimiento (incluida la interacción del usuario).
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;
if (took < count)
{
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);
Sin embargo, si usted está después de la actuación, y en el código de producción, estamos todos después de la actuación, no se debe utilizar paginación de LINQ como se muestra arriba, sino más bien el subyacente IEnumerator
para implementar la paginación mismo. Como cuestión de hecho, es tan simple como la LINQ-algoritmo mostrado anteriormente, pero más performant:
const int pageSize = 10;
const int count = 100;
const int startIndex = 20;
int took = 0;
bool getNextPage = true;
using (var page = ideas.Skip(startIndex).GetEnumerator())
{
do
{
Console.WriteLine("Page {0}:", (took/pageSize) + 1);
int currentPageItemNo = 0;
while (currentPageItemNo++ < pageSize && page.MoveNext())
{
var idea = page.Current;
Console.WriteLine(idea);
}
took += pageSize;
if (took < count)
{
Console.WriteLine("Next page (y/n)?");
char answer = Console.ReadLine().FirstOrDefault();
getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);
}
}
while (getNextPage && took < count);
}
Explicación: La desventaja de usar Skip()
para múltiples veces en una "forma en cascada" es, que lo hará realmente no almacena el "puntero" de la iteración, donde se saltó por última vez. - En cambio, la secuencia original se cargará de frente con saltos de llamadas, lo que conducirá a "consumir" las páginas ya "consumidas" una y otra vez. - Puede probarlo usted mismo, cuando crea la secuencia ideas
para que produzca efectos secundarios. -> Incluso si se salteó 10-20 y 20-30 y quiere procesar más de 40, verá todos los efectos secundarios de 10-30 ejecutándose nuevamente, antes de comenzar a iterar 40+. La variante que usa la interfaz IEnumerable
directamente, en su lugar recordará la posición del final de la última página lógica, por lo que no se requiere omisión explícita y los efectos secundarios no se repetirán.
Lo resolví de forma un poco diferente de lo que tienen los demás ya que tuve que hacer mi propio paginador, con un repetidor. Así que hice por primera vez una colección de números de página para la colección de artículos que tengo:
// 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]
El uso de este podría fácilmente dividir el punto de recogida en una colección de "páginas". Una página en este caso es solo una colección de artículos (IEnumerable<Item>
). Esta es la forma en que puede hacerlo utilizando Skip
y Take
junto con la selección del índice de la pageRange
creado anteriormente:
IEnumerable<IEnumerable<Item>> pageRange
.Select((page, index) =>
myItems
.Skip(index*PageSize)
.Take(PageSize));
Por supuesto, usted tiene que manejar cada página como una colección, pero por ejemplo, si anida repetidores, entonces esto es realmente fácil de manejar.
La sola línea versión TLDR sería la siguiente:
var pages = Enumerable
.Range(0, pageCount)
.Select((index) => myItems.Skip(index*PageSize).Take(PageSize));
que puede ser utilizado como esto:
for (Enumerable<Item> page : pages)
{
// handle page
for (Item item : page)
{
// handle item in page
}
}
- 1. Paginación Datalist con linq
- 2. Crear una colección de SelectListItem con LINQ
- 3. ¿Linq para actualizar una colección con valores de otra colección?
- 4. LINQ, creando colección única de una colección
- 5. Ordenando una colección observable con linq
- 6. LINQ y paginación
- 7. LINQ y paginación con una vista de lista
- 8. Linq con colección base personalizada
- 9. ¿Cómo LINQ ordeno una colección
- 10. consultar una subcolección de una colección con linq
- 11. Contando palabras en una colección usando LINQ
- 12. Colección de cadena usando LINQ
- 13. Linq: Encontrar elemento en una colección
- 14. Comprueba si un valor está en una colección con LINQ
- 15. ¿Dividir una colección en partes según la condición con LINQ?
- 16. Filtrar una colección con LINQ frente a CollectionView
- 17. LINQ - filtrar colección infantil
- 18. Colección LINQ GroupBy
- 19. LINQ paginación - obtener los registros totales
- 20. LINQ: Búsqueda de una colección dentro de una colección para un solo objeto
- 21. La colección personalizada de Magento rompe la paginación
- 22. Ordenar la colección dentro de la colección usando Linq
- 23. LInq que consulta la colección dentro de la colección
- 24. Consultar y actualizar una propiedad en una colección usando LINQ
- 25. ¿Busca con premura múltiples propiedades de colección (utilizando QueryOver/Linq)?
- 26. ¿LINQ admite de forma nativa dividir una colección en dos?
- 27. se cruzan una colección de colecciones en LINQ
- 28. cómo combinar una colección de colecciones en Linq
- 29. linq seleccionar elementos de la colección infantil
- 30. LINQ DONDE método modifica colección de origen
yo creo que está bien hacer algo como esto. Él podría tener una respuesta, pero tal vez él quiere ver lo que otras personas pueden aportar también. –
Esto se publicó originalmente durante el primer día del período beta de StackOverflow, por lo tanto, el 66 para la ID del artículo. Estaba probando el sistema, para Jeff. Además, me pareció información útil en lugar de la típica basura de prueba que a veces sale de las pruebas beta. –