Tengo dos expresiones de tipo Expression<Func<T, bool>>y quiero tomar OR, AND o NOT de estas y obtener una nueva expresión del mismo 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
fuente
                
                fuente

Respuestas:
Bueno, puedes usar
Expression.AndAlso/OrElseetc para combinar expresiones lógicas, pero el problema son los parámetros; ¿Estás trabajando con lo mismoParameterExpressionen expr1 y expr2? Si es así, es más fácil:Esto también funciona bien para negar una sola operación:
De lo contrario, dependiendo del proveedor de LINQ, puede combinarlos con
Invoke:En algún lugar, tengo un código que reescribe un nodo de reemplazo de árbol de expresión para eliminar la necesidad
Invoke, pero es bastante largo (y no puedo recordar dónde lo dejé ...)Versión generalizada que elige la ruta más simple:
A partir de .NET 4.0, existe la
ExpressionVisitorclase que le permite crear expresiones que son seguras para EF.fuente
ExpressionVisitor) no existía en ese entonces; Tengo un ejemplo relacionado sobre stackoverflow de una fecha similar donde implementa el visitante manualmente: es mucho código.Puede usar Expression.AndAlso / OrElse para combinar expresiones lógicas, pero debe asegurarse de que las Expresiones de parámetros sean las mismas.
Estaba teniendo problemas con EF y PredicateBuilder, así que hice el mío sin recurrir a Invoke, que podría usar así:
Código fuente para mi PredicateBuilder:
Y la clase de utilidad para sustituir los parámetros en una lambda:
fuente
Si su proveedor no es compatible con Invoke y necesita combinar dos expresiones, puede usar un ExpressionVisitor para reemplazar el parámetro en la segunda expresión por el parámetro en la primera expresión.
fuente
No hay nada nuevo aquí, pero casé esta respuesta con esta respuesta y la refacté un poco para que incluso yo entienda lo que está sucediendo:
fuente
Necesitaba lograr los mismos resultados, pero usando algo más genérico (ya que el tipo no se conocía). Gracias a la respuesta de Marc, finalmente descubrí lo que estaba tratando de lograr:
fuente
Sugiero una mejora más para PredicateBuilder y sus
ExpressionVisitorsoluciones. Lo llaméUnifyParametersByNamey puedes encontrarlo en la biblioteca mita de MIT: LinqExprHelper . Permite combinar expresiones arbitrarias lambda. Por lo general, las preguntas se hacen sobre la expresión predicada, pero esta idea también se extiende a las expresiones de proyección.El siguiente código emplea un método
ExprAdresque crea una expresión parametrizada complicada, usando lambda en línea. Esta expresión complicada se codifica solo una vez y luego se reutiliza, gracias a laLinqExprHelpermini biblioteca.Y este es el código de construcción de subexpresión:
Lo que intenté lograr fue realizar consultas parametrizadas sin necesidad de copiar y pegar y con la capacidad de usar lambdas en línea, que son muy bonitas. Sin todas estas cosas de expresión auxiliar, me vería obligado a crear una consulta completa de una vez.
fuente
Creo que esto funciona bien, ¿no?
fuente