0

У меня есть запрос следующим образом:Использование существующего IQueryable для создания нового динамического IQueryable

var query = from x in context.Employees 
    where (x.Salary > 0 && x.DeptId == 5) || x.DeptId == 2 
    order by x.Surname 
    select x; 

Выше исходный запрос и возвращает скажем 1000 объектов для сотрудников.

Теперь я хотел бы использовать первый запрос к деконструкции его и воссоздать новый запрос, который будет выглядеть следующим образом:

var query = from x in context.Employees 
    where ((x.Salary > 0 && x.DeptId == 5) || x.DeptId == 2) && (x,i) i % 10 == 0 
    order by x.Surname 
    select x.Surname; 

Этот запрос будет возвращать 100 фамилий.

Синтаксис, вероятно, неверен, но мне нужно сделать следующее: добавьте дополнительное предложение where и измените выбор на одно поле.

Я искал ExpressionVisitor, но я не совсем уверен, как создать новый запрос на основе существующего запроса.

Любое руководство будет оценено по достоинству. Спасибо вам.

ответ

0

В выражении посетителя вы переопределили вызов метода. Проверьте, является ли метод Queryable.Where, и если да, то второй параметр методов - это выраженное выражение выражения lambda типа. Рыбу это, и вы можете прикрутить его.

static void Main() 
    { 
     IQueryable<int> queryable = new List<int>(Enumerable.Range(0, 10)).AsQueryable(); 
     IQueryable<string> queryable2 = queryable 
      .Where(integer => integer % 2 == 0) 
      .OrderBy(x => x) 
      .Select(x => x.ToString()); 
     var expression = Rewrite(queryable2.Expression); 
    } 

    private static Expression Rewrite(Expression expression) 
    { 
     var visitor = new AddToWhere(); 
     return visitor.Visit(expression); 
    } 

    class AddToWhere : ExpressionVisitor 
    { 
     protected override Expression VisitMethodCall(MethodCallExpression node) 
     { 
      ParameterExpression parameter; 
      LambdaExpression lambdaExpression; 
      if (node.Method.DeclaringType != typeof(Queryable) || 
       node.Method.Name != "Where" || 
       (lambdaExpression = ((UnaryExpression)node.Arguments[1]).Operand as LambdaExpression).Parameters.Count != 1 || 
       (parameter = lambdaExpression.Parameters[0]).Type != typeof(int)) 
      { 
       return base.VisitMethodCall(node); 
      } 
      return Expression.Call(
       node.Object, 
       node.Method, 
       this.Visit(node.Arguments[0]), 
       Expression.Quote(
        Expression.Lambda(
         lambdaExpression.Type, 
         Expression.AndAlso(
          lambdaExpression.Body, 
          Expression.Equal(
           Expression.Modulo(
            parameter, 
            Expression.Constant(
             4 
            ) 
           ), 
           Expression.Constant(
            0 
           ) 
          ) 
         ), 
         lambdaExpression.Parameters 
        ) 
       ) 
      ); 
     } 
    } 
} 
Смежные вопросы