【问题标题】:Get all 'where' calls using ExpressionVisitor使用 ExpressionVisitor 获取所有 'where' 调用
【发布时间】:2011-05-29 18:28:33
【问题描述】:

我有一个查询,例如:

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”的类来获得第一个,该类来自于 TerraServer 的自定义查询提供程序的 MSDN 教程网络服务。

它是:

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 对象。

【问题讨论】:

    标签: c# linq expression-trees iqueryable lambda


    【解决方案1】:

    使用在此处找到的类 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;
            }
        }
    

    【讨论】:

    • 谢谢,这行得通。还有一个问题...您知道是否可以从 Exp 树中删除某些 where 子句?
    • 在您的 VisitMethodCall 中,您要将表达式添加到列表中。您可以进行某种测试,然后您可以将第二个参数替换为常量条件,而不是返回表达式。像 1 == 1
    猜你喜欢
    • 2016-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 2020-10-17
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    相关资源
    最近更新 更多