简体   繁体   English

SelectMany之后无法通过ExpressionVisitor找到Where表达式

[英]Cannot find Where expression with ExpressionVisitor after SelectMany

I have a ExpressionVisitor derived class with following overridden VisitMethodCall() method. 我有一个ExpressionVisitor派生类,它具有以下重写的VisitMethodCall()方法。

class CommonExpressionVisitor : ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if (node.Method.DeclaringType == typeof(Queryable))
        {
            switch (node.Method.Name)
            {
                case nameof(Queryable.Where):
                    Visit(node.Arguments[0]);
                    return node;

                case nameof(Queryable.Select):
                    Visit(node.Arguments[0]);
                    return node;

                case nameof(Queryable.SelectMany):
                    Visit(node.Arguments[0]);
                    Visit(node.Arguments[1]);
                    Visit(node.Arguments[2]);
                    return node;
            }
        }
        return base.VisitMethodCall(node);
    }
}

The visitor can easily find Where expression when there is no SelectMany call in the query. 当查询中没有SelectMany调用时,访问者可以轻松地找到Where表达式。 Such as: 如:

var queryable = from item in collection
                where item.X >= 0 && item.Y >= 0
                select item;

However, if the query contains SelectMany , the entire Where expression is gone and the visitor is unable to reach it anymore. 但是,如果查询包含SelectMany ,则整个Where表达式都消失了,访问者将无法再访问它。

var queryable = from item in collection
                from sub in item.SubItems
                where sub.A >= 0 && sub.B >= 0
                select sub;

How do I fix my ExpressionVisitor in order to find Where expression? 如何修复ExpressionVisitor以便查找Where表达式?

Going to answer my own question. 要回答我自己的问题。 There are two phases in the expression. 表达式有两个阶段。 In first phase the IQueryable.Provider property is called to generate anonymous objects that consists of two variables item and sub . 在第一阶段,将调用IQueryable.Provider属性以生成由两个变量itemsub组成的匿名对象。 In second phase, same property is called again where the expression now contains the anonymous type and where clause. 在第二阶段,再次调用相同的属性,其中表达式现在包含匿名类型和where子句。 So the where clause does not disappear, it is just in second phase. 所以where子句不会消失,它只是在第二阶段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM