Linq PredicateBuilder com filtros condicionais AND, OR e NOT
Temos um projeto usando LINQ to SQL, para o qual preciso reescrever algumas páginas de pesquisa para permitir que o cliente selecione se deseja executar ume ou umou procurar.
Eu pensei em refazer as consultas LINQ usandoPredicateBuilder e tenho isso funcionando muito bem, eu acho. Eu efetivamente tenho uma classe que contém meus predicados, por exemplo:
internal static Expression<Func<Job, bool>> Description(string term)
{
return p => p.Description.Contains(term);
}
Para realizar a pesquisa, estou fazendo isso (algum código foi omitido por questões de brevidade):
public Expression<Func<Job, bool>> ToLinqExpression()
{
var predicates = new List<Expression<Func<Job, bool>>>();
// build up predicates here
if (SearchType == SearchType.And)
{
query = PredicateBuilder.True<Job>();
}
else
{
query = PredicateBuilder.False<Job>();
}
foreach (var predicate in predicates)
{
if (SearchType == SearchType.And)
{
query = query.And(predicate);
}
else
{
query = query.Or(predicate);
}
}
return query;
}
Embora eu esteja razoavelmente feliz com isso, tenho duas preocupações:
Os blocos if / else que avaliam uma propriedade SearchType parecem que podem ser um cheiro de código em potencial.O cliente agora está insistindo em poder executar pesquisas 'e não' / 'ou não'.Para abordar o ponto 2, acho que poderia fazer isso reescrevendo minhas expressões, por exemplo:
internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
if (invert)
{
return p => !p.Description.Contains(term);
}
else
{
return p => p.Description.Contains(term);
}
}
No entanto, isso parece um pouco complicado, o que geralmente significa que há uma solução melhor por aí. Alguém pode recomendar como isso pode ser melhorado? Estou ciente do LINQ dinâmico, mas realmente não quero perder a digitação forte do LINQ.