ASP.NET - Paginação com LINQ usando take e skip


No artigo   LINQ - Apresentando os operadores Take e Skip - eu apresentei os operadores Take e Skip mostrando a sua utilização básica. Vou mostrar agora como criar a paginação dinâmica em  páginas ASP.NET usando estes operadores LINQ.

Nota: No sítio http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx você tem uma relação dos operadores com exemplos sobre cada um deles.

Para acompanhar os exemplos deste artigo você deverá ter instalado o Visual Web Developer 2008 Express Edition e o SQL Server 2005 Express.

Se não tiver pegue aqui:

Abra o Visual Web Developer 2008 Express (VWD 2008E) e no menu File selecione o item New Web Site; a seguir selecione o template ASP .NET Web Site, Location File System , language Visual Basic e informe o nome do site : aspnet_pagLinq

A seguir inclua uma referência ao LINQ To SQL. No menu WebSite selecione Add new Item e na janela Templates selecione LINQ To SQl Classes informando o nome Northwind.dbml pois iremos acessar o banco de dados Northwind.mdf. Com isso estamos criando o DataContext que é o objeto que gerencia o acesso aos dados sendo também o responsável por traduzir as alterações realizadas nos objetos e refleti-las para o banco de dados via SQL e vice-versa.

Neste momento será apresentada a janela de aviso abaixo solicitando a confirmação para incluir o arquivo .dbml na pasta App_Code. Confirme.

A seguir vamos definir uma conexão com o banco de dados Northwind.mdf; se a conexão ainda não existir no seu ambiente faça o seguinte:

1- No menu View e selecione DataBase Explorer e clique com o botão direito do  mouse sobre o item Data Connections e selecione Add Connection...

2- Na janela Add Connection Clique no botão Browse e selecione o banco de dados Northwind.mdf a partir do local onde você o instalou e clique no botão Abrir;

Será apresenta a janela de aviso abaixo solicitando a confirmação para copiar o arquivo para a pasta App_Data no seu projeto. Confirme.

Abra a janela DataBase Explorer e expanda os objetos do banco de dados. Selecione as tabelas: Products, Orders, Categories e Order Details , arraste e solte na janela do Descritor Objeto Relacional. O descritor irá criar as classes mapeadas para cada tabela do banco de dados e você verá o esquema das classes conforme figura a seguir;

Note que o descritor LINQ To SQL cria as classes a partir das tabelas. Assim a tabela Products resultou na classe Product e a tabela Categories na tabela Category. Estes nomes tornam o seu modelo consistente com a convenção usada pelo framework .NET e são convenientes na maioria dos casos.

Se você não gostar dos nomes dados às classes ou às propriedades mapeadas que o descritor gerou você pode alterá-los editando diretamente o nome da entidade/propriedade no próprio descritor ou via janela de propriedades.

Perceba que a nova versão apresenta mais uma forma de visualização no descritor. Selecionando Split você terá uma visão do código fonte e do Design simultânea onde qualquer alteração em um deles será refletida imediatamente no outro.

A partir da janela ToolBox selecione a guia Data e arraste um componente GridView para a página Default.aspx .

A seguir inclua também um componente Literal que será usado para exibir os índices das páginas.

Agora vamos ao código da página Default.aspx , antes vamos alterar o nome da página para Produtos.aspx. (Clique com o botão direito sobre a página Default.aspx e selecione Rename informando o novo nome)

Após esta alteração abra o arquivo Produtos.aspx.vb , o code-behind, e declare o datacontext na página :

Dim db As New NorthwindDataContext

A seguir no evento Load da página inclua o seguinte código:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim linhaInicio As Integer = Convert.ToInt32(Request.QueryString("linhaInicio"))

mostraProdutos(linhaInicio)

End Sub

Neste código criamos uma variável linhaInicio que será usada como parâmetro para rotina mostraProdutos().

O valor da variável é obtido de um QueryString e tem o valor inicial igual a zero.

O código da rotina mostraProdutos() é o seguinte:

Private Sub mostraProdutos(ByVal linhaInicio As Integer)

Dim consulta = From p In db.Products _
                      Where
p.CategoryID > 2 And p.UnitPrice > 3 _
                      Order
By p.ProductID _

                      Select
p.ProductID, p.ProductName, p.UnitPrice, p.QuantityPerUnit

Dim totalRegs As Integer = consulta.Count()

Dim tamPagina As Integer = 10

Dim totalPaginas As Integer = totalRegs / tamPagina

 

If totalRegs Mod 10 > 0 Then

    totalPaginas += 1

End If

 

Dim sb As New StringBuilder()

 

For i As Integer = 0 To totalPaginas - 1

    Dim pagNo As Integer = i + 1

    sb.Append("<a href='Produtos.aspx?linhainicio=" + (tamPagina * i).ToString + "'>" + pagNo.ToString + "</a> ")

Next

 

Literal1.Text = "Pag. : " + sb.ToString()

 

GridView1.DataSource = consulta.Skip(linhaInicio).Take(10)

GridView1.DataBind()

End Sub

A consulta LINQ seleciona o código, nome , preço unitário e quantidade do produto ordenando por código para os produtos com preço unitário maior que 3 e categoria maior que 2.

A seguir obtemos o total de registros obtidos definimos o tamanho da página em 10 itens e obtemos o total de Páginas dividindo o total de registros pelo tamanho da página.

Criamos um objeto StringBuilder() e efetuamos uma concatenação dos números das páginas com um link para a página Produtos.aspx?linhainicio=?  onde ? refere-se ao índice da página

Nota:  Veja o artigo sobre StringBuilder: VB .NET - StringBuilder : tratando Strings de modo mais eficiente

 Quando formos exibir os dados no gridview usamos o operador Skip : consulta.Skip(linhaInicio).Take(10)  , onde linha de início refere-se ao índice da página.

O resultado pode ser visto na tela a seguir:

Pegue o projeto completo aqui :  aspnet_pagLinq.zip

Eu sei é apenas ASP.NET e LINQ , mas eu gosto...


José Carlos Macoratti