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 atalhoCom 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.
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(); } }