Obtenga todas las llamadas 'donde' usando ExpressionVisitor

c# expression-trees iqueryable lambda linq

Pregunta

Tengo una consulta, como tal:

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

Quiero implementar un ExpressionVisitor para extraer AMBAS cláusulas where como Lambda, pero hasta ahora solo he podido obtener la primera utilizando una clase llamada 'InnermostWhereFinder' que viene del tutorial de MSDN en un proveedor de consultas personalizadas para el servicio web TerraServer .

Es:

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

He intentado ajustar esta clase para devolver ambas cláusulas sin éxito. No se pudo encontrar una gran documentación sobre esto, ¿alguien puede ayudar? Creo que, en última instancia, esto tendrá que generar múltiples objetos LambdaExpression con los que pueda trabajar.

Respuesta aceptada

Use la clase que se encuentra aquí en http://msdn.microsoft.com/en-us/library/bb882521%28v=vs.90%29.aspx como su base. A continuación, puede crear su visitante de esta manera

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


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow