J'ai deux expressions de type Expression<Func<T, bool>>
et je veux passer à OU, ET ou NON de celles-ci et obtenir une nouvelle expression du même type
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
la source
la source
Réponses:
Eh bien, vous pouvez utiliser
Expression.AndAlso
/OrElse
etc pour combiner des expressions logiques, mais le problème réside dans les paramètres; travaillez-vous avec le mêmeParameterExpression
dans expr1 et expr2? Si oui, c'est plus simple:Cela fonctionne également bien pour annuler une seule opération:
Sinon, selon le fournisseur LINQ, vous pourrez peut-être les combiner avec
Invoke
:Quelque part, j'ai du code qui réécrit un arbre d'expression remplaçant les nœuds pour supprimer le besoin
Invoke
, mais il est assez long (et je ne me souviens pas où je l'ai laissé ...)Version généralisée qui choisit l'itinéraire le plus simple:
À partir de .NET 4.0, il existe la
ExpressionVisitor
classe qui vous permet de créer des expressions qui sont sécurisées par EF.la source
ExpressionVisitor
) n'existait pas à l'époque; J'ai un exemple connexe sur stackoverflow à partir d'une date similaire où il implémente le visiteur manuellement: c'est beaucoup de code.Vous pouvez utiliser Expression.AndAlso / OrElse pour combiner des expressions logiques, mais vous devez vous assurer que les ParameterExpressions sont les mêmes.
J'avais des problèmes avec EF et PredicateBuilder alors j'ai créé le mien sans recourir à Invoke, que je pourrais utiliser comme ceci:
Code source de mon PredicateBuilder:
Et la classe d'utilité pour remplacer les paramètres dans un lambda:
la source
Si votre fournisseur ne prend pas en charge Invoke et que vous devez combiner deux expressions, vous pouvez utiliser un ExpressionVisitor pour remplacer le paramètre dans la deuxième expression par le paramètre dans la première expression.
la source
Rien de nouveau ici, mais a épousé cette réponse avec cette réponse et l'a légèrement remaniée afin que même je comprenne ce qui se passe:
la source
J'avais besoin d'obtenir les mêmes résultats, mais en utilisant quelque chose de plus générique (car le type n'était pas connu). Grâce à la réponse de marc, j'ai finalement compris ce que j'essayais de réaliser:
la source
Je suggère une amélioration supplémentaire à PredicateBuilder et aux
ExpressionVisitor
solutions. Je l'ai appeléUnifyParametersByName
et vous pouvez le trouver dans la bibliothèque du MIT: LinqExprHelper . Il permet de combiner des expressions lambda arbitraires. Habituellement, les questions sont posées sur l'expression des prédicats, mais cette idée s'étend également aux expressions de projection.Le code suivant utilise une méthode
ExprAdres
qui crée une expression paramétrée compliquée, en utilisant lambda en ligne. Cette expression compliquée n'est codée qu'une seule fois, puis réutilisée, grâce à laLinqExprHelper
mini-bibliothèque.Et voici le code de construction de la sous-expression:
Ce que j'ai essayé de réaliser était d'exécuter des requêtes paramétrées sans avoir besoin de copier-coller et avec la possibilité d'utiliser des lambdas en ligne, qui sont si jolis. Sans tous ces trucs d'expression d'aide, je serais obligé de créer une requête entière en une seule fois.
la source
Je pense que cela fonctionne bien, non?
la source