使用ExpressionVisitor获取所有“where”调用

时间:2010-12-23 02:58:49

标签: c# linq expression-trees iqueryable lambda

我有一个查询,例如:

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子句作为Lambda,但到目前为止只能使用一个名为'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;
        }
    }

我已经尝试过大量调整这个类来返回where子句没有成功。找不到任何关于此的好文档,有人可以帮忙吗?我认为这最终需要产生多个可以使用的LambdaExpression对象。

1 个答案:

答案 0 :(得分:6)

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