Eu tenho duas expressões do tipo Expression<Func<T, bool>>
e quero levar para OR, AND ou NOT desses e obter uma nova expressão do mesmo tipo
Expression<Func<T, bool>> expr1;
Expression<Func<T, bool>> expr2;
...
//how to do this (the code below will obviously not work)
Expression<Func<T, bool>> andExpression = expr AND expr2
c#
linq
lambda
expression
BjartN
fonte
fonte
Respostas:
Bem, você pode usar
Expression.AndAlso
/OrElse
etc para combinar expressões lógicas, mas o problema são os parâmetros; você está trabalhando com o mesmoParameterExpression
em expr1 e expr2? Nesse caso, é mais fácil:Isso também funciona bem para negar uma única operação:
Caso contrário, dependendo do provedor LINQ, você poderá combiná-los com
Invoke
:Em algum lugar, tenho um código que reescreve uma árvore de expressão que substitui os nós para remover a necessidade
Invoke
, mas é bastante demorado (e não me lembro onde o deixei ...)Versão generalizada que escolhe a rota mais simples:
A partir do .NET 4.0, existe a
ExpressionVisitor
classe que permite criar expressões que são seguras pelo EF.fonte
ExpressionVisitor
) não existia naquela época; Eu tenho um exemplo relacionado no stackoverflow a partir de uma data semelhante em que implementa o visitante manualmente: é muito código.Você pode usar Expression.AndAlso / OrElse para combinar expressões lógicas, mas é necessário garantir que as ParameterExpressions sejam as mesmas.
Eu estava tendo problemas com a EF e o PredicateBuilder, então criei o meu próprio sem recorrer ao Invoke, que eu poderia usar assim:
Código fonte do meu PredicateBuilder:
E a classe de utilitário para substituir os parâmetros em um lambda:
fonte
Se seu provedor não suportar Invoke e você precisar combinar duas expressões, poderá usar um ExpressionVisitor para substituir o parâmetro na segunda expressão pelo parâmetro na primeira expressão.
fonte
Nada de novo aqui, mas casou-se com esta resposta com esta resposta e ligeiramente reformulado-lo de modo que mesmo eu entendo o que está acontecendo:
fonte
Eu precisava alcançar os mesmos resultados, mas usando algo mais genérico (como o tipo não era conhecido). Graças à resposta de Marc, finalmente descobri o que estava tentando alcançar:
fonte
Sugiro mais uma melhoria para o PredicateBuilder e
ExpressionVisitor
soluções. Eu chameiUnifyParametersByName
e você pode encontrá-lo na minha biblioteca do MIT: LinqExprHelper . Permite combinar expressões lambda arbitrárias. Geralmente, as perguntas são feitas sobre a expressão de predicado, mas essa idéia se estende também às expressões de projeção.O código a seguir emprega um método
ExprAdres
que cria uma expressão parametrizada complicada, usando lambda embutido. Essa expressão complicada é codificada apenas uma vez e depois reutilizada, graças àLinqExprHelper
mini-biblioteca.E este é o código de construção da subexpressão:
O que eu tentei realizar foi realizar consultas parametrizadas sem a necessidade de copiar e colar e com a capacidade de usar lambdas em linha, que são muito bonitas. Sem todas essas coisas de expressão auxiliar, eu seria forçado a criar uma consulta inteira de uma só vez.
fonte
Eu acho que isso funciona bem, não é?
fonte