Criando query dinamicas no Entity Framework com LinqKit

0

Criação de query dinâmicas nem sempre é uma coisa muito fácil de se fazer. Com a evolução e popularização das tecnologias ORM (ex:  Entity e Hibernate) está cada vez mais usual a criação de consultas complexas e aos poucos comandos T-SQL e Storeds Procedures estão sendo descontinuadas.

Claro que storeds e comandos SQL sempre irão existir, por N motivos, mas isto não vem ao caso agora. Vamos falar da facilidade de criação de “Where” e “If” em consultas com Entity Framework. Vamos utilizar LINQKit

Vamos à definição do LINQKit oferecida pelo autor:

LINQKit é um conjunto gratuito de extensões para LINQ para usuários avançados do Entity Framework e do SQL. Ela compreende o seguinte:

• Uma implementação extensível de AsExpandable ()
• Uma classe de expressão pública de base visitante (ExpressionVisitor)
• PredicateBuilder
Linq.Expr e Linq.Func métodos de atalho

Com LINQKit, você pode:

• Ligue expressões em EntitySets e EntityCollections
Use variáveis ​​de expressão em subconsultas
• Combine expressões (têm uma expressão chamar outro)
Dinamicamente construir predicados
Alavancar AsExpandable para adicionar suas próprias extensões.

• AsExpandable é baseado em um projeto muito inteligente por Tomas Petricek. ExpressionVisitor vem de uma amostra por Matt Warren.

LINQKit inclui código fonte completo, e é distribuído sob uma licença livre permissiva.

Você pode ler exemplos e mais sobre a ferramenta aqui : http://www.albahari.com/nutshell/linqkit.aspx
Você pode fazer o download da ferramenta pelo Nuget:
Veja um exemplo utilizando bastante recursos da ferramenta :
       public ICollection<Pergunta> Consultar(string titulo, int ordenacao, int pagina, int registrosPorPagina, out int totalRegistros)
        {
            //Criando um predicado LinqKit do objeto Pergunta
            var predicate = PredicateBuilder.True<Pergunta>();

            //Adicionando um "Where" caso o titulo não seja nulo 
            if (!string.IsNullOrEmpty(titulo))
                predicate = predicate.And(p => p.Texto.Contains(titulo));

            //Adicionando clausula de Status
            predicate = predicate.And(p => p.Status == (byte)Pergunta.enumStatusPergunta.Ativo);

            //Recebendo o total de registros
            totalRegistros = base.dbset.AsExpandable().Where(predicate).Count();

            //Adicionando if e ordenando pelo tipo de ordenacao desejada
            if (ordenacao == 1)
            {
                //Retornando o predicado usando orderby e paginação
                return base.dbset.AsExpandable().Where(predicate)
               .OrderByDescending(x => x.DataCadastro)
               .Skip((pagina - 1) * registrosPorPagina)
               .Take(registrosPorPagina).ToList();
            }
            else
            {
                //Retornando o predicado usando orderby e paginação
                return base.dbset.AsExpandable().Where(predicate)
              .OrderBy(x => x.DataCadastro)
              .Skip((pagina - 1) * registrosPorPagina)
              .Take(registrosPorPagina).ToList();
            }
        }
        
Bom, espero que façam mais uso da ferramenta, porém tomem um pouco de cuidado, mas acredito que a criação de predicados afeta o desempenho da consulta.
Bom, por hoje é só!
Tá afim de fazer um curso de HTML 5 de graça oferecido pela Microsoft? Clique aqui! 🙂
Compartilhe.

Sobre o autor

Criador do blog Código Simples e com mais 9 anos de experiência em TI, com títulos de MVP Microsoft na área de Visual Studio Development, Neo4j Top 50 Certificate, Scrum Master e MongoDB Evangelist. Atuando em funções analista, desenvolvedor, arquiteto, líder técnico e gestor de equipes. Mais informações em : http://jhonathansoares.com