Obtenez tous les appels "où" à l'aide d'ExpressionVisitor

c# expression-trees iqueryable lambda linq

Question

J'ai une requête, comme celle-ci:

var query = from sessions in dataSet
                    where (names.Contains(sessions.Username))
                    where (sessions.Login.TimeOfAction == dt)                    
                    select new {    sessions.Username, 
                                    sessions.Login, 
                                    sessions.Logout, sessions.Duration };

Je souhaite implémenter un ExpressionVisitor afin d'extraire les deux clauses where en tant que Lambda, mais je n'ai jusqu'à présent réussi à obtenir le premier qu'à l'aide d'une classe appelée 'InnermostWhereFinder' issue du didacticiel MSDN sur un fournisseur de requêtes personnalisé pour le service Web TerraServer .

C'est:

internal class InnermostWhereFinder : ExpressionVisitor
    {
        private MethodCallExpression innermostWhereExpression;

        public MethodCallExpression GetInnermostWhere(Expression expression)
        {
            Visit(expression); 
            return innermostWhereExpression;
        }

        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            if (expression.Method.Name == "Where")
                innermostWhereExpression = expression;

            Visit(expression.Arguments[0]);

            return expression;
        }
    }

J'ai essayé de peaufiner fortement cette classe pour renvoyer les deux clauses où sans succès. Impossible de trouver une excellente documentation à ce sujet, quelqu'un peut-il aider? Je pense que cela doit finalement aboutir à plusieurs objets LambdaExpression avec lesquels je peux travailler.

Réponse acceptée

Utilisez la classe trouvée ici http://msdn.microsoft.com/en-us/library/bb882521%28v=vs.90%29.aspx comme base. Vous pouvez ensuite créer votre visiteur comme ceci

internal class WhereFinder : ExpressionVisitor
    {
        private IList<MethodCallExpression> whereExpressions = new List<MethodCallExpression>();

        public IList<MethodCallExpression> GetWhere(Expression expression)
        {
            Visit(expression); 
            return whereExpressions;
        }

        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            if (expression.Method.Name == "Where")
                whereExpressions.Add(expression);

            Visit(expression.Arguments[0]);

            return expression;
        }
    }


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi