Получить все вызовы "где", используя ExpressionVisitor - PullRequest
3 голосов
/ 23 декабря 2010

У меня есть запрос, например:

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

Я хочу реализовать ExpressionVisitor, чтобы извлекать оба предложения where как лямбда-выражения, но до сих пор удалось получить только первое, используя класс InnermostWhereFinder, полученный из учебного пособия по MSDN о поставщике пользовательских запросов для TerraServer. веб-сервис.

Это:

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

Я пытался настроить этот класс, чтобы вернуть оба предложения безуспешно. Не можете найти отличную документацию по этому вопросу, кто-нибудь может помочь? Я думаю, что в конечном итоге это приведет к созданию нескольких объектов LambdaExpression, с которыми я могу работать.

1 Ответ

6 голосов
/ 23 декабря 2010

Используйте найденный здесь класс http://msdn.microsoft.com/en-us/library/bb882521%28v=vs.90%29.aspx в качестве базы. Затем вы можете создать своего посетителя следующим образом

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