Как извлечь дерево выражений предложения where из IQueryable - PullRequest
0 голосов
/ 11 января 2019

Мне нужно динамически добавлять предложение «И» в предложении where в зависимости от некоторых условий для существующего объекта IQueryable.

Используя ExpressionBuilder, я могу составить левое и правое Выражение>, но для этого мне нужно извлечь Выражение> из моего экземпляра IQueryable. Возможно ли это?

Пример кода:

var list = _context.Set<T>().Where(x=>x.Id == 1);

if(someValue)
{
    var leftExpression = list.???? //I would extract the Expression<Func<T, bool>> here
    var orExpression = (T x) => x.Status == 1;

    var newWhereClause = ExpressionBuilder.Or(leftExpression, orExpression);
    list = list.Where(newWhereClause);
}

Код ExpressionBuilder был взят по этой ссылке: https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/

Спасибо!

1 Ответ

0 голосов
/ 12 января 2019

Что вам нужно сделать, это сломать исходное IQueryable, извлечь источник и выражение запроса, а затем создать новое выражение запроса, а затем новый IQueryable из источника и нового выражения запроса. Если нет Where, просто добавьте условие к исходному запросу.

IQueryable<T> q = _context.Set<T>().Where(x => x.Id == 1);

if(someValue) {
    Expression<Func<T,bool>> newWhereClause = (T x) => x.Status == 1;
    Expression source;

    if (q.Expression is MethodCallExpression qe && qe.Method.Name == "Where") {
        var we = (MethodCallExpression)q.Expression; // get the call to Where
        var wea1 = (UnaryExpression)we.Arguments[1]; // get the 2nd arg to Where (Quoted Lambda)
        var leftExpr = (Expression<Func<T, bool>>)wea1.Operand; // Extract the lambda from the QuoteExpression
        newWhereClause = ExpressionBuilder.Or(leftExpr, newWhereClause);
        q = q.Provider.CreateQuery<T>(we.Arguments[0]).Where(newWhereClause);
    }
    else
        q = q.Where(newWhereClause);
}

Обратите внимание, что это зависит от внутренних элементов LINQ и деревьев выражений и может сломаться в какой-то момент в будущем.

...