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 NorthwindDataContextA 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