Artigo recomendado para Visual Studio 2008,SQLServer 2005/2008.

A internet n√£o √© mais a mesma desde o lan√ßamento dos primeiros cadastros de sites que deram inicio aos grandes portais de busca que temos hoje. Em fun√ß√£o dos poderosos indexadores precisamos otimizar o conte√ļdo e links da aplica√ß√£o web de forma que ela seja melhor entendida e indexada. A esse conjunto de t√©cnicas de marketing focado em indexa√ß√£o de conte√ļdo que deu-se origem ao termo SEO (Search engine optimization). Utilizando o ASP.NET temos diversos caminhos a otimizar fazendo com  que a aplica√ß√£o exposta na web de forma p√ļblica seja melhor entendida e um deles √© a pagina√ß√£o de registros que vamos implementar nesse artigo.

Vale ressaltar que essa técnica de paginação utilizara o
LINQ (Language Integrated Query) para o melhor desempenho e SQLServer 2005 ou 2008 com numeração de linhas. Você também pode substituir o LINQ por uma Stored Procedure e adaptar o mesmo exemplo para uso no Visual Studio 2005 com tableAdapter.

Após criação do novo projeto web o próximo passo é criar o diagrama de classe do LINQ para o mapeamento da tabela Produtcs do banco de dados exemplo '
Northwind' conforme Figura 01. Lembrando que esse banco de dados deve est√° rodando no servidor SQLServer.



Figura 01 - Tabela Products mapeada como classe Product no LINQ.

Agora para completar o projeto adicione um webform Produtos.aspx e um usercontrol chamado de ucPaginacao.ascx que usaremos para conter a interface de paginação. Durante a implementação desse exemplo utilizaremos um Repeater para exibir os dados, porém como o mesmo não possui paginação estamos justamente desenvolvendo nesse artigo.

Retornando ao nosso formulário adicione um Repeater e configure conforme o código HTML da Listagem 01.

Produtos.aspx
   1:  <asp:Repeater ID="Repeater1" runat="server">
   2:          <ItemTemplate>
   3:          <%#Eval("Codigo")%>
   4:          <%#Eval("Descricao")%>
   5:          <br />
   6:          
   7:          </ItemTemplate>
   8:  </asp:Repeater>
Listagem 01 - Configurando controle Repeater.

O Próximo passo é arrastar o controle ucPaginacao para pagina produtos.aspx. Em seguida criaremos o método Carregar() dentro do nosso WebForm 'Produtos'. Esse método será o responsável pela consulta no banco de dados usando o LINQ e trará apenas um bloco especifico de registros otimizando a paginação ao máximo. Confira na Listagem 02.

Carregar()
   1:  /// <summary>
   2:  /// Obter dados do banco de dados
   3:  /// Traz apenas um grupo especifico de registros.
   4:  /// </summary>
   5:  private void Carregar()
   6:  {
   7:              var pagina = 0;
   8:              var db = new PaginacaoDBDataContext();
   9:              var totalRegistros = (from p in db.Products
  10:                           select p).Count();
  11:              if (PaginaAtual != 0)
  12:              { pagina = PaginaAtual * MaximoRegistrosPagina; }
  13:   
  14:   
  15:            var dados = (from p in db.Products
  16:                           orderby p.ProductID 
  17:                           select new
  18:                           {  
  19:                               Codigo = p.ProductID,
  20:                               Descricao = p.ProductName
  21:                           }
  22:   
  23:                    ).Skip(pagina).Take(MaximoRegistrosPagina);
  24:   
  25:              this.Repeater1.DataSource = dados;
  26:              this.Repeater1.DataBind();
  27:              ConfiguraPaginacao(totalRegistros);
  28:  }
Listagem 02 - Implementando método Carregar().

Conforme voc√™ est√° observando nessa listagem usando a linguagem de consulta do LINQ estamos obtendo um conjunto especifico de registros que est√£o determinados pelo par√Ęmetro Skip() e Take(). Confira na Listagem 03 um exemplo de c√≥digo T-SQL gerado automaticamente.

T-SQL Paginação
   1:  SELECT [t1].[ProductID] AS [Codigo], [t1].[ProductName] AS
 [Descricao]
   2:  FROM (
   3:      SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ProductID]) AS
 [ROW_NUMBER], [t0].[ProductID], [t0].[ProductName]
   4:      FROM [dbo].[Products] AS [t0]
   5:      ) AS [t1]
   6:  WHERE [t1].[ROW_NUMBER] BETWEEN 10 + 1 AND 10 + 10
   7:  ORDER BY [t1].[ROW_NUMBER]
Listagem 03 -Código T-SQL gerado pelo LINQ

A l√≥gica implementada na Listagem 02 tem objetivo de extrair do banco de dados a pagina atual calculada pela  quantidade de registros no banco de dados (Listagem 02 - Linha 09), mais o tamanho da pagina (padr√£o 10 registros) e o par√Ęmetro pagina atual que ser√° usado para determinar os par√Ęmetros do m√©todo Skip().

Para criar o link de avançar e retornar pelos registros foi implementado uma regra dentro do controle ucPaginacao onde configuramos pelo método
ConfiguraPaginacao() apresentado na Listagem 04.

ConfiguraPaginacao()
   1:  /// <summary>
   2:  /// Configurando controle de paginação
   3:  /// </summary>
   4:  /// <param name="total"></param>
   5:  private void ConfiguraPaginacao(int totalRegistros)
   6:  {
   7:              
   8:       PaginacaoParametros parametros = new PaginacaoParametros();
   9:       parametros.TotalRegistros = totalRegistros;
  10:       parametros.PaginaAtual = PaginaAtual;
  11:       parametros.MaximoRegistrosPagina = MaximoRegistrosPagina;
  12:       ucPaginacao1.Carregar(parametros);
  13:  }
Listagem 04 -Implementação do método ConfiguraPaginacao().

Conforme Listagem 04 nesse m√©todo estamos usando a classe PaginacaoParametros criada dentro do UserControl com objetivo de passar par√Ęmetros para o controle por meio do m√©todo Carregar() apresentado na linha 12.

Examinando o controle ucPaginacao na Listagem 05 perceba que adicionamos dois controles HyperLink justamente para utilizarmos os links em HTML de forma que as ferramentas de busca possam navegar por todas as paginas automaticamente. Como elas navegam em todos links html que encontram v√£o avan√ßar todas as paginas at√© o final registrando em suas bases de dados todo o conte√ļdo.

ucPaginacao.ascx
   1:  <%@ Control Language="C#" AutoEventWireup="true"
   2:   CodeBehind="ucPaginacao.ascx.cs"
   3:    Inherits="PaginacaoSEOLinq.ucPaginacao" %>
   4:  <br style="clear: both;" />
   5:  <div id="Navigation" runat="server">
   6:  <div id="navegacao">
   7:  <a id="PreviousPageNav" runat="server"> &lt;&lt; Voltar</a>             
   8:  <asp:Label ID="PagerLocation" runat="server" />
   9:  <asp:HyperLink ID="Link1" runat="server"></asp:HyperLink>
  10:  <a id="NextPageNav" runat="server">Avançar &gt;&gt;</a>
  11:  </div>       
  12:  </div>
Listagem 05 -Código html do ucPaginacao.

Numa r√°pida vis√£o dentro do c√≥digo do controle ucPaginacao apresentado na Listagem 06 estamos implementando os m√©todos necess√°rios para configurar o controle conforme os dados recebidos e exibir as informa√ß√Ķes para mostrar os links atrav√©s do m√©todo UpdateNextPrevLinks. Parte do c√≥digo fonte foi suprimido por est√° dispon√≠vel para download junto com o c√≥digo fonte.

ucPaginacao.ascx
   1:  public partial class ucPaginacao : System.Web.UI.UserControl
   2:  {
   3:   private PaginacaoParametros configuracao;
   4:   protected void Page_Load(object sender, EventArgs e)
   5:   {
   6:   }
   7:   public void Carregar(PaginacaoParametros config)
   8:   {
   9:   }
  10:   void UpdatePagerLocation(int pageIndex, int 
pageSize, int productCount)
  11:   {
  12:   }
  13:   void UpdateNextPrevLinks(int pageIndex,
 int pageSize, int productCount)
  14:   {          
  15:   }
  16:  }
Listagem 06 -Implementação do controle ucPaginacao.

A id√©ia principal de usar esse UserControl √© reutilizar o mesmo em todas as paginas bastando arrastar e configurar os par√Ęmetros. Confira o mesmo em a√ß√£o na Figura 02 e acompanhe tamb√©m o par√Ęmetro da pagina atual passado na url.


Figura 02 - Paginação em ação.

Durante esse artigo você observou uma implementação usando LINQ com objetivo de realizar paginação atendendo aos critérios do SEO (Search engine optimization) que atingimos pela paginação usando Hyperlink. Esse artigo foi preparado também de forma que você possa substituir o código do LINQ por uma paginação usando TableAdapter ou código manual diretamente usando ADO.NET para ser compatível com Visual Studio 2005.
 

Código Fonte:
[
Download]


Esse artigo foi baseado no banco de dados ''NorthWind".
Referência:
 ASP.NET 2.0 - Paginando dados com SQLServer (2000/2005)
Linq para iniciantes - Visual Studio 2008
Efficient Data Paging with the ASP.NET 2.0 DataList Control and ObjectDataSource