如何从 IQueryable 中提取 where 子句表达式树
How to extract a where clause expression tree from IQueryable
我需要根据现有 IQueryable 对象的某些条件,在 where 子句中动态添加 "Or" 子句。
使用 ExpressionBuilder,我可以组成一个左右 Expression>,但要正常工作,我需要从我的 IQueryable 实例中提取 Expression>。
可能吗?
示例代码:
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 代码取自此link:
https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
谢谢!
您要做的是分解原始的 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 和表达式树的内部结构,将来可能会中断。
我需要根据现有 IQueryable 对象的某些条件,在 where 子句中动态添加 "Or" 子句。
使用 ExpressionBuilder,我可以组成一个左右 Expression>,但要正常工作,我需要从我的 IQueryable 实例中提取 Expression>。 可能吗?
示例代码:
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 代码取自此link: https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
谢谢!
您要做的是分解原始的 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 和表达式树的内部结构,将来可能会中断。