Using ExpressionVisitor, get all 'where' calls.

c# expression-trees iqueryable lambda linq

Question

I have the following question:

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 };

Using a class named "InnermostWhereFinder" from the MSDN guide on creating a custom query provider for the TerraServer web service, I've only been able to extract the first of the two where clauses as Lambda's, while wanting to create an ExpressionVisitor to extract BOTH as Lambda's.

It is:

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;
        }
    }

Without success, I tried substantially modifying this class to return both where clauses. I was unable to locate any excellent material on this; can someone assist? I believe the end result will need to be many LambdaExpression objects that I can use.

1
3
12/23/2010 3:09:07 AM

Accepted Answer

Use the class http://msdn.microsoft.com/en-us/library/bb882521%28v=vs.90%29.aspx provided here as your starting point. After that, you may construct your Visitor using this.

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;
        }
    }
6
12/23/2010 3:16:11 AM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow