在 SelectMany 之后无法使用 ExpressionVisitor 找到 Where 表达式
Cannot find Where expression with ExpressionVisitor after SelectMany
我有一个 ExpressionVisitor
派生的 class 具有以下被覆盖的 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);
}
}
当查询中没有 SelectMany
调用时,访问者可以轻松找到 Where
表达式。如:
var queryable = from item in collection
where item.X >= 0 && item.Y >= 0
select item;
但是,如果查询包含 SelectMany
,整个 Where
表达式将消失,访问者将无法再访问它。
var queryable = from item in collection
from sub in item.SubItems
where sub.A >= 0 && sub.B >= 0
select sub;
如何修复我的 ExpressionVisitor
以找到 Where
表达式?
要回答我自己的问题。表达式中有两个阶段。在第一阶段调用 IQueryable.Provider
属性 生成由两个变量 item
和 sub
组成的匿名对象。在第二阶段,再次调用相同的 属性,其中表达式现在包含匿名类型和 where
子句。所以 where
子句并没有消失,它只是在第二阶段。
我有一个 ExpressionVisitor
派生的 class 具有以下被覆盖的 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);
}
}
当查询中没有 SelectMany
调用时,访问者可以轻松找到 Where
表达式。如:
var queryable = from item in collection
where item.X >= 0 && item.Y >= 0
select item;
但是,如果查询包含 SelectMany
,整个 Where
表达式将消失,访问者将无法再访问它。
var queryable = from item in collection
from sub in item.SubItems
where sub.A >= 0 && sub.B >= 0
select sub;
如何修复我的 ExpressionVisitor
以找到 Where
表达式?
要回答我自己的问题。表达式中有两个阶段。在第一阶段调用 IQueryable.Provider
属性 生成由两个变量 item
和 sub
组成的匿名对象。在第二阶段,再次调用相同的 属性,其中表达式现在包含匿名类型和 where
子句。所以 where
子句并没有消失,它只是在第二阶段。