Menu

Paginado eficiente de grillas Parte 1/2

septiembre 23, 2013 - ASP.NET

La opción por defecto que presenta un GridView para el paginado funciona bastante bien, por qué alguien querría cambiarla? sencillo, alguna vez te has puesto a pensar como se hace este paginado automático?.

Hablemos de los tipos de pagina de una grilla, existen dos tipos a saber:

Default paging: Puede ser implementado simplemente habilitando la opcion de Enable Pagina en la SmartTag del GridView. Cuando se activa esta opcion lo que hace el control es traer TODOS los registros de la consulta, calcula internamente el subconjunto de datos que debe mostrar y desecha el resto mostrando solo los registros pertinentes en pantalla.

Custom paging: Permite la implementacion personalizada de un sistema de paginacion, manejando nosotros totalmente el código.

Debido a la facilidad de hacer clic en el check de Enable Paging, la opcion de default paging puede ser bastante atractiva y de hecho la recomiendo en aplicaciones donde no se manejen gran cantidad de registros (o la consulta que realiza no consuma mucho tiempo ni recursos), pero si tenemos millones de registros, una consulta compleja esta ya no es una opción viable pues será supremamente ineficiente.

Nota: En la última versión de SQL Server 2012 se creo una clausula especial para el paginado, este tutorial esta enfocado a como realizarse en versiones anteriores de SQL Server.

Requisitos

En el tutorial voy a usar Visual Studio 2010 (Sin embargo usare .NET Framework 2.0) y SQL Server 2012 con la base de datos AdventureWorks.

Como paginar de forma personalizada?

Lo primero que tenemos que entender es como funciona el paginado, voy a explicar brevemente como implementarlo de la manera mas común y menos traumática.

Digamos que tenemos 100 registros y vamos a mostrarlos en una grilla en grupos de 10 registros a la vez entonces, la primera vez se mostraran los registros 1 al 10, en la segunda pagina lo registros 11 al 20, y así sucesivamente, asi pues necesitamos unos cuantos conceptos para realizar nuestro acometido:

Habiendo aclarado estos conceptos llegó la hora de ponernos…

Manos a la obra!

1, 2, 3…. Contando los registros

Lo primero que vamos a implementar es un procedimiento almacenado que nos devuelva el total de registros que existen en nuestra consulta, como lo que vamos a hacer es mostrar los registros de una tabla la consulta será un COUNT(1):

CREATE PROCEDURE uspTotalRecordCount
AS
BEGIN

SET NOCOUNT ON;

SELECT
COUNT(1) 'COUNT'
FROM
Person.Person
END

image

Luego de haber contado los registros podemos proceder a consultar el subconjunto de datos preciso que queremos mostrar para ello existen dos formas de hacerlo:

En este tutorial usaremos la versión con ROW_NUMBER().

Dame solo lo que necesito!

Primero escribimos la consulta que necesitamos con la clausula ROW_NUMBER(), asi:

SELECT
FirstName,
LastName,
PersonType,
ROW_NUMBER() OVER (ORDER BY BusinessEntityID) 'ItemNo'
FROM
Person.Person

El resultado que genera es el siguiente:

image

Una parte importantísima de este enfoque es que en el ROW_NUMBER se debe especificar en el OVER la condición de ordenamiento, en este caso lo organice por BusinessEntityID, pero deben asegurarse que el campo de ordenamiento cumpla con los requisitos de su consulta. Luego de tener la consulta lista se puede hacer una consulta sobre esta agregándole una clausula WHERE especificando cuales registros necesitamos:

SELECT
FirstName,
LastName,
PersonType
FROM
(SELECT
FirstName,
LastName,
PersonType,
ROW_NUMBER() OVER (ORDER BY BusinessEntityID) 'ItemNo'
FROM Person.Person
) AS PersonPaged
WHERE
PersonPaged.ItemNo BETWEEN 11 AND 20

Resultado:

image

Una vez tenemos la consulta que queremos podemos ajustarla en un procedimiento almacenado utilizando los conceptos que vimos recientemente de StartRowIndex y MaximumRows.

CREATE PROCEDURE [dbo].[uspGetPersonPaged]
@StartRowIndex INT,
@MaximumRows INT
AS
BEGIN
SET NOCOUNT ON;
SELECT
FirstName,
LastName,
PersonType
FROM
(SELECT
FirstName,
LastName,
PersonType,
ROW_NUMBER() OVER (ORDER BY BusinessEntityID) 'ItemNo'
FROM
Person.Person
) AS PersonPaged
WHERE
PersonPaged.ItemNo BETWEEN @StartRowIndex AND @StartRowIndex + (@MaximumRows - 1)
END

Si ejecutamos el método enviándole como parámetro StartRowIndex en 11 y MaximumRows en 10, este sera el resultado que obtendremos:

image

Eso es todo por ahora, en la próxima entrega veremos con implementar esto en un GridView.

Happy coding! Sonrisa

2 pensamientos sobre “Paginado eficiente de grillas Parte 1/2

  • Pingback: Paginado eficiente de grillas Parte 2/2 | EduardoOrtega.me()

  • Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *