Paginação utilizando LINQ


Podemos facilmente vincular uma query LINQ em um controle DataBound do ASP.NET para exibir os dados. A query pode ser feita utilizando LINQ To SQL, LINQ To Xml, etc. Com isso, podemos simplesmente fazer:

this.GridView1.DataSource = from cliente in colecaoDeClientes select cliente;
this.GridView1.DataBind();

Os problemas aparecem quando voce habilita a paginação do controle e, ao rodar o mesmo exemplo, uma exceção do tipo NotSupportedException será disparada, informando a seguinte mensagem: The data source does not support server-side data paging. Quando efetuamos uma query LINQ (em cima de qualquer fonte de informação), o retorno é sempre uma classe que implementa direta ou indiretamente a Interface IEnumerable<T>, e para efetuar a paginação, é necessário que o controle conheça a quantidade de registros retornados pela query para conseguir dimensionar a quantidade necessária de páginas a serem exibidas.

A Interface referida acima não possui uma propriedade que informe a quantidade de elementos da coleção e, como alternativa, podemos alterar a query para que ela retorne uma instancia da classe List<T>, modificando ligeiramente a query:

this.GridView1.DataSource = (from cliente in colecaoDeClientes select cliente).ToList();
this.GridView1.DataBind();

Anúncios

4 comentários sobre “Paginação utilizando LINQ

  1. Esse tipo de paginação é eficente? Por exemplo se eu tenho um table com 50.000 registros e fizer um select que vai retorar todos os registros essa paginação ela vai trazer todos os 50.000 registro no objeto certo?

  2. Boas Tarcisio,

    Sim, para melhor performance, o ideal é "fatiar" o result-set.

    A idéia do post foi somente para mostrar o "problema" que existe ao utilização a paginação com uma query LINQ.

  3. Mas invocando o método .ToList() desta forma, não perco a funcionalidade de deferred executiondo LINQ? Os exemplos que costumeiramente vejo, utilizam .Skip() e .Take() para realizar a paginação.

  4. Boas Bruno,

    O post originou em um cenário específico, onde estava exatamente o que mostrei aí, ou seja, o vinculado direto da query na propriedade DataSource de um controle DataBound. Naquele caso específico, ela precisava da massa de dados (que não era grande) para fazer algumas manipulações antes de exibí-la.

    Mas no geral, o ideal é mesmo efetuar a paginação do lado do servidor, utilizando os métodos Skip e Take para "fatiar" o result-set diretamente no banco de dados, ao invés de trazer tudo isso para a aplicação.

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