domingo, 28 de setembro de 2008

Queries Dinâmicas com LINQ

Recentemente fui implementar um exemplo simples de queries dinâmicas no LINQ, e me deparei com um grande obstáculo. “Queries dinâmicas” são aquelas que criamos em tempo de execução, geralmente com a concatenação de strings.

Pense numa aplicação que o usuário escolha dinamicamente os campos que vão fazer parte do filtro da sua pesquisa. Essa é uma necessidade muito comum, e com as classes convencionais do ADO.NET e comandos SQL, essa é uma tarefa bastante simples.

Como sabemos, no LINQ criamos nossas queries no próprio código (C# / VB.NET), onde databases, tabelas e campos são objetos fortemente tipados. É consenso geral que essa é a grande benesse do LINQ, e fator principal do seu sucesso. Porém em cenários de queries dinâmicas, como o citado acima, temos um sério problema.

A primeira solução que encontrei para este problema, de cara não me agradou muito, dada a sua complexidade. A idéia é “construir” a query LINQ em Lambda Expressions, que podem ser feitas em tempo de execução, de acordo com os parâmetros definidos.

Não vou entrar em detalhes em como fazer isso, mas deixo aqui um ótimo artigo do Renato Guimarães sobre esse assunto:
http://renatoguimaraes.spaces.live.com/Blog/cns!256AF1F8919FD3B1!1251.entry. E outro do Joseph Albahari: http://www.albahari.com/nutshell/predicatebuilder.aspx.

Com um pouco mais de pesquisa, encontrei uma solução bem mais adequada para o problema: O LINQ Dynamic Query Library.

Isso na verdade, é uma pequena biblioteca construída pela galera de desenvolvimento do LINQ na Microsoft, que permite a criação de queries LINQ dinâmicas, com a concatenação de strings.

Essa biblioteca é distribuída em um pacote de exemplos que você pode baixar para C#:
http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

Ou VB.NET:
http://msdn.microsoft.com/en-us/vbasic/bb964686.aspx

Em ambos os pacotes você vai encontrar um diretório chamado DynamicQuery que contém um exemplo de como utilizar esse pacote.

Para você ter uma idéia de como funciona o LINQ Dynamic Query Library, o que você faz tradicionalmente com LINQ, assim:



Com as queries dinâmicas você pode fazer assim:


Caiu como uma luva para o problema que eu precisava resolver. Além desse pacote, nos downloads citados acima você vai encontrar uma séria de exemplos úteis para LINQ.

Confira também este post do Scott Guthrie sobre o assunto:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Grande Abraço e até a próxima!

5 comentários:

  1. Caro Rodrigo,

    Li seu artigo, achei bem interessante e estou tentando utiliza-lo em uma solução com VS2008 atualizado, e tive problemas para adicionar a biblioteca, pois eu baixe a versão em VB, e adiciono ela no meu projeto, e apresenta diversos erros, que não esta localizando a System.

    Sabe porque isto acontece ? Ou estou fazendo o procedimento errado para adicionar ?

    obrigado
    Edson

    ResponderExcluir
  2. Uma dúvida, no seu exemplo se o usuário não informasse a cidade, como ficaria; se fosse algo onde ele pudesse escolher uma cidade (ai incluiria ela no filtro) ou não, trazendo todas?

    ResponderExcluir
  3. O ideal neste caso é que você não inclua a cidade na condição where. Então, se o usuário omitir o valor de um determinado campo, ele não aparece no filtro.

    ResponderExcluir
  4. Prezado Rodrigo,

    Estou utilizando o Dynamic LINQ, mas não funcionou uma LIKE Expression, você teria como me dar um Exemplo?

    ResponderExcluir
  5. Olá Frederico,
    Substitua o Like por .StartsWith(), .EndsWith() ou.Contains(). Isso deve resolver o problema.
    Abs!

    ResponderExcluir