在 linq 中使用的动态 where 表达式
Dynamic where expression to use in linq
我想构建一个动态 where 表达式以在对象列表上使用。
var list = new List<Dummy>();
IQueryable<Dummy> queryableData = list.AsQueryable<Dummy>();
MethodCallExpression wherExpression =
Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Dummy) },
queryableData.Expression,
Expression.Lambda<Func<Dummy, bool>>(lambda.Body, lambda.Parameters.First()));
更新: lambda.Body
lambda.Body = {(((x.Title.Contains("Mihai") Or x.Description.Contains("Mihai")) Or x.Comments.Contains("Mihai")) Or x.User.Contains("Mihai"))}
然后像这样调用 where 表达式:
var result = queryableData.Provider.CreateQuery<Dummy>(wherExpression).ToList();
where 子句构建正确,这就是结果
{System.Collections.Generic.List`1[P.Dummy].Where(x => (((x.Title.Contains("Foo") Or x.Description.Contains("Foo")) Or x.Comments.Contains("Foo")) Or x.User.Contains("Foo")))}
当我尝试调用 where 表达式时,我得到
var result = queryableData.Provider.CreateQuery<Dummy>(wherExpression).ToList();
variable 'x' of type 'P.Dummy' referenced from scope '', but it is not defined
你知道为什么吗?你能帮我解决吗?
更新
表达式的构造方式如下:
var type = typeof(T);
var lambdaList = new List<Expression<Func<T, bool>>>();
foreach (var prop in type.GetProperties())
{
if (prop.PropertyType == typeof(string))
{
ParameterExpression parameter = Expression.Parameter(type, "x");//{x}
Expression expression = parameter;
PropertyInfo pi = type.GetProperty(prop.Name);//Property
expression = Expression.Property(expression, pi);//{x.Property}
var containsFunc = Expression.Call(expression,
typeof(string).GetMethod("Contains"),
new Expression[] { Expression.Constant("Mihai") });
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(containsFunc, parameter);
lambdaList.Add(lambda);
}
}
Expression<Func<T, bool>> finalExpression = lambdaList.First();
foreach (Expression<Func<T, bool>> expression in lambdaList.Skip(1))
{
finalExpression = finalExpression.Or(expression);
}
评论副本:
我知道你的问题了。您为每个 属性 创建一个新的 ParameterExpression。它们都称为 x 但它们是不同的实例。只创建一个名为 x 的 ParameterExpression,然后遍历所有属性。
我想构建一个动态 where 表达式以在对象列表上使用。
var list = new List<Dummy>();
IQueryable<Dummy> queryableData = list.AsQueryable<Dummy>();
MethodCallExpression wherExpression =
Expression.Call(typeof(Queryable),
"Where",
new Type[] { typeof(Dummy) },
queryableData.Expression,
Expression.Lambda<Func<Dummy, bool>>(lambda.Body, lambda.Parameters.First()));
更新: lambda.Body
lambda.Body = {(((x.Title.Contains("Mihai") Or x.Description.Contains("Mihai")) Or x.Comments.Contains("Mihai")) Or x.User.Contains("Mihai"))}
然后像这样调用 where 表达式:
var result = queryableData.Provider.CreateQuery<Dummy>(wherExpression).ToList();
where 子句构建正确,这就是结果
{System.Collections.Generic.List`1[P.Dummy].Where(x => (((x.Title.Contains("Foo") Or x.Description.Contains("Foo")) Or x.Comments.Contains("Foo")) Or x.User.Contains("Foo")))}
当我尝试调用 where 表达式时,我得到
var result = queryableData.Provider.CreateQuery<Dummy>(wherExpression).ToList();
variable 'x' of type 'P.Dummy' referenced from scope '', but it is not defined
你知道为什么吗?你能帮我解决吗?
更新 表达式的构造方式如下:
var type = typeof(T);
var lambdaList = new List<Expression<Func<T, bool>>>();
foreach (var prop in type.GetProperties())
{
if (prop.PropertyType == typeof(string))
{
ParameterExpression parameter = Expression.Parameter(type, "x");//{x}
Expression expression = parameter;
PropertyInfo pi = type.GetProperty(prop.Name);//Property
expression = Expression.Property(expression, pi);//{x.Property}
var containsFunc = Expression.Call(expression,
typeof(string).GetMethod("Contains"),
new Expression[] { Expression.Constant("Mihai") });
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(containsFunc, parameter);
lambdaList.Add(lambda);
}
}
Expression<Func<T, bool>> finalExpression = lambdaList.First();
foreach (Expression<Func<T, bool>> expression in lambdaList.Skip(1))
{
finalExpression = finalExpression.Or(expression);
}
评论副本:
我知道你的问题了。您为每个 属性 创建一个新的 ParameterExpression。它们都称为 x 但它们是不同的实例。只创建一个名为 x 的 ParameterExpression,然后遍历所有属性。