Explorando o GridView – Paginação de Dados


Há momentos em que o result-set da base de dados é muito grande, ou seja, é retornado ao cliente uma grande quantidade de registros, o que pode custar muito caro para o mesmo pois recebe todos os registros e exibe apenas os registros que se enquadram na página atual, e limitando ao número de registros por páginas.

A paginação de dados vem justamente para suprir esta necessidade, podendo dar ao usuário uma forma mais simples de navegar pelo result-set e consequentemente, a aplicação ganha muito em performance. O controle GridView já fornece uma arquitetura que permite a paginação automática de registros.

A forma de como habilitar esta opção é idêntica à ordenação de colunas que fizemos anteriormente, ou seja, deve-se clicar na Smart Tag do controle GridView e marcar o CheckBox chamado Enable Paging, como é ilustrado na figura abaixo:

Figura 1 – Habilitando a Paginação de Registros.

Habilitando esta opção, o controle GridView já fará a paginação dos registros automaticamente. Através do código HTML abaixo da página ASPX, vemos como o mesmo ficou configurado:

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    AllowPaging="True"             
    AutoGenerateColumns="False" 
    DataSourceID="SqlDataSource1"
    PageSize="2">
    <Columns>
        <asp:BoundField 
            DataField="Nome" 
            HeaderText="Nome" />
        <asp:BoundField 
            DataField="Email" 
            HeaderText="Email" />
    </Columns>
</asp:GridView>
ASPX  

Uma nova propriedade é apresentada: PageSize. Ela é responsável por definir a quantidade de registros que serão apresentados por página.

Utilizando o objeto SqlDataSouce

Como neste objeto temos a propriedade DataSourceMode, onde definimos qual será a forma de recuperar os dados da fonte de dados (Dataset ou DataReader), infelizmente ele não pode ser definido como DataReader, pois para efetuar a paginação o objeto deverá obrigatoriamente implementar a interface ICollection, que é somente o caso do objeto Dataset. Vale lembrar que isso já é um problema conhecido nas versões 1.x do ASP.NET.

Para conseguir a paginação de forma automática temos que definir a propriedade DataSourceMode como Dataset ou omití-la. Mas é importante dizer que nada impedirá você de criar uma paginação e controle customizados para esta situação.

Utilizando o objeto ObjectDataSouce

Ao utilizar este tipo de objeto temos que fazer alguns ajustes para habilitar a paginação no controle GridView. Apesar de existir algumas formas diferentes de se fazer, no exemplo mostrado abaixo a paginação retornará apenas os registros pertinentes a página solicitada pelo usuário. Logo a Stored Procedure responsável por retornar estes registros deve receber dois parâmetros:

  • PageNumber – O número da página requisitada pelo usuário.
  • PageSize – Quantidade de registros por página.

Abaixo é exibida a Stored Procedure que utiliza subqueries para retornar a quantidade de registros de uma determinada página:

ALTER PROCEDURE dbo.CustomPaging 
    @PageSize As Int,    
    @PageNumber As Int AS
	
    DECLARE @COUNTER As Int
    SET @COUNTER = (SELECT COUNT(*) FROM Usuario)
	
    IF @PageNumber = 0
        SET @PageNumber = 1
	
    SELECT Nome FROM Usuario
        WHERE UsuarioID IN 
            (SELECT TOP(@PageSize) UsuarioID FROM Usuario
                WHERE UsuarioID NOT IN 
                    (SELECT TOP(@PageSize * (@PageNumber - 1)) UsuarioID FROM Usuario
                        ORDER BY Nome)
            ORDER BY Nome)
        ORDER BY Nome
			
    RETURN @COUNTER
T-SQL  

Agora com o SQL Server 2005 e o SQL Server Express 2005, a cláusula TOP do T-SQL pode ser parametrizada, o que nas versões anteriores só conseguíamos através de uma query dinâmica. A quantidade total de registros (que utilizamos a função COUNT para recuperar) é necessária, pois o objeto ObjectDataSource precisa desse valor para calcular as páginas à serem exibidas ao usuário.

Depois da Stored Procedure pronta vamos analisar a classe de negócios que receberá os parâmetros e executará a Stored Procedure acima. Abaixo o código da classe de negócios:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web;
using System.Web.Configuration;
using System.Collections.Generic;

public class Paging
{
    private int _count = 0;

    public int TotalUsuarios(){
        return this._count;
    }

    public List ResgataUsuarios(int pageSize, int pageNumber)
    {
        List coll = new List();
        SqlConnection conn = new SqlConnection(
            WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
        SqlCommand cmd = new SqlCommand("CustomPaging", conn);

        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("@PageSize", pageSize);
        cmd.Parameters.AddWithValue("@PageNumber", pageNumber);
        cmd.Parameters.AddWithValue("@RETURN_VALUE", 0).Direction = 
            ParameterDirection.ReturnValue;

        SqlDataReader dr = null;
        try
        {
            conn.Open();
            dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            while (dr.Read())
            {
                Usuario u = new Usuario();
                u.Nome = dr.GetString(0);
                coll.Add(u);
            }
        }
        finally
        {
            if (dr != null)
                dr.Close();

            this._count = 
                Convert.ToInt32(cmd.Parameters["@RETURN_VALUE"].Value);
        }
        return coll;
    }
}
C# VB.NET  

Analisando o código acima, temos um membro privado na classe Paging, que é responsável por armazenar a quantidade total de registros da base de dados (ou da condição da cláusula SQL). O método ResgataUsuarios que recebe os parâmetros pageSize e o pageNumber, os quais já descrevemos acima suas utilidades, e através dele os mesmos são anexados à coleção de parâmetros do objeto SqlCommand que executa a Stored Procedure.

Através de um objeto SqlDataReader percorremos os registros da base de dados e populamos o objeto Usuario que posteriormente é adicionado à uma coleção genérica deste mesmo tipo.

Já o método TotalUsuarios retorna o valor contido dentro do membro privado denominado _count, o qual representa a quantidade total de registros da base de dados (ou da condição da cláusula SQL). Como já foi falado, o objeto ObjectDataSource ou qualquer outro tipo de paginação requer este valor para calcular e exibir a quantidade de páginas disponíveis ao usuário. Recuperamos este valor total através de um parâmetro do tipo RETURN_VALUE, que a Stored Procedure retorna para a aplicação.

Através do código HTML abaixo da página ASPX, vemos como configurar o objeto ObjectDataSource e o controle GridView corretamente:

<asp:ObjectDataSource 
    ID="ObjectDataSource1" 
    runat="server" 
    EnablePaging="True"
    SelectCountMethod="TotalUsuarios"                     
    StartRowIndexParameterName="pageNumber"
    MaximumRowsParameterName="pageSize"
    SelectMethod="ResgataUsuarios"
    TypeName="Paging">
</asp:ObjectDataSource>    

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    AllowPaging="True" 
    AutoGenerateColumns="False"
    DataSourceID="ObjectDataSource1"
    PageSize="2">
    <Columns>
        <asp:BoundField 
            DataField="Nome" 
            HeaderText="Nome" />
    </Columns>
</asp:GridView>
ASPX  

Analisando o código HTML da página ASPX acima, vemos duas propriedades que já são de nosso conhecimento: a SelectMethod e TypeName, que foram descritas na seção sobre Tipos de DataSource. Abaixo são listadas as propriedades do objeto ObjectDataSource que ainda não analisamos:

  • EnablePaging – É necessário definir para True quando queremos habilitar a paginação de registros no objeto ObjectDataSource.

  • SelectCountMethod – Definimos nesta propriedade o nome do método da classe de negócios que é responsável por retornar a quantidade total de registros.

  • StartRowIndexParameterName – Baseando-se na classe de negócios que criamos acima, esta propriedade é definida com o nome do parâmetro (pageNumber) responsável pela página que o usuário requisitou.

  • MaximumRowsParameterName – Baseando-se na classe de negócios que criamos acima, esta propriedade é definida com o nome do parâmetro (pageSize) responsável pela quantidade de registros exibidos por página.

Já na configuração do controle GridView não se tem muito à fazer: temos que definir a fonte de dados a ser utilizada; habilitar a paginação através da propriedade AllowPaging e, finalmente, através da propriedade PageSize definir a quantidade de registros que serão exibidos por página. Realizados esses ajustes, o GridView já está pronto para realizar a paginação de registros sem a necessidade de definirmos os valores aos parâmetros, pois o controle GridView em conjunto com o objeto ObjectDataSource fará isso de forma transparente.

A imagem abaixo exibe o controle GridView já em funcionamento utilizando o objeto ObjectDataSource como fonte de dados:

Figura 2 – GridView em funcionamento.

GridView.zip (674.49 kb)

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s