我有一个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);
}
}当查询中没有Where调用时,访问者可以很容易地找到SelectMany表达式。例如:
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表达式?
发布于 2018-04-03 02:04:49
回答我自己的问题。表达式有两个阶段。在第一阶段,调用IQueryable.Provider属性以生成由两个变量item和sub组成的匿名对象。在第二阶段,在表达式现在包含匿名类型和where子句的地方再次调用相同的属性。因此,where子句并没有消失,它只是处于第二阶段。
https://stackoverflow.com/questions/49493283
复制相似问题