Desenvolvimento - ASP. NET
Otimizando a paginação do ASP.NET para SEO usando LINQ
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.
por Ramon Durães
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.
1: <asp:Repeater ID="Repeater1" runat="server">
2: <ItemTemplate>
3: <%#Eval("Codigo")%>
4: <%#Eval("Descricao")%>
5: <br />
6:
7: </ItemTemplate>
8: </asp: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: }
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]
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.
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: }
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"> << 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 >></a>
11: </div>
12: </div>
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: }
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