动态LINQ或条件
我希望使用LINQ在集合上执行多个where条件,类似于动态LINQ或条件,linq,Linq,我希望使用LINQ在集合上执行多个where条件,类似于 IEnumerable<Object> items; items.Where(p => p.FirstName = "John"); items.Where(p => p.LastName = "Smith"); 不行 基本上,我想做的是: foreach(var name in names) { items = items.Where(p => p.Name == name); } 听起来您的白
IEnumerable<Object> items;
items.Where(p => p.FirstName = "John");
items.Where(p => p.LastName = "Smith");
不行
基本上,我想做的是:
foreach(var name in names)
{
items = items.Where(p => p.Name == name);
}
听起来您的白名单只有在运行时才知道。也许可以试试这个:
string[] names = new string[] {"John", "foo", "bar"};
var matching = items.Where(x => names.Contains(x.Name));
使用:
假设您想编写一个LINQ到SQL或实体框架查询,以实现关键字样式的搜索。换句话说,一个查询返回的行的描述包含给定关键字集的部分或全部
理想的方法是动态构造执行基于or的谓词的lambda表达式树
在所有促使您手动构建表达式树的因素中,对动态谓词的需求是典型业务应用程序中最常见的。幸运的是,可以编写一组简单且可重用的扩展方法,从根本上简化此任务。这是我们的PredicateBuilder类的角色
您可以使用.Union()
返回满足任何条件的结果
var results = items.Where(p => p.FirstName == "John")
.Union(items.Where(p => p.LastName == "Smith"));
这不如使用
|
运算符。您的编辑不清楚为什么这样做行不通。您不能使Where
子句动态,但可以动态创建传递给它的Lambda表达式。创建right,编译它并将结果lambda表达式作为参数传递给Where子句
编辑:
好的,似乎您可以跳过必须手动创建表达式并可用于该表达式的部分,正如所回答的。公共静态表达式或seFiltersTogether(
这是(可数过滤器)
{
表达式firstFilter=filters.FirstOrDefault();
if(firstFilter==null)
{
表达式alwaysTrue=x=>true;
始终返回;
}
var body=firstFilter.body;
var param=firstFilter.Parameters.ToArray();
foreach(过滤器中的var nextFilter.Skip(1))
{
var nextBody=Expression.Invoke(nextFilter,param);
body=Expression.OrElse(body,nextBody);
}
表达式结果=表达式.Lambda(body,param);
返回结果;
}
然后,稍后:
List<Expression<Func<Person, bool>>> filters = names
.Select<string, Expression<Func<Person, bool>>>(name =>
p => p.Name == name
).ToList();
Expression<Func<Person, bool>> filterOfOrs = filters.OrTheseFiltersTogether();
query = query.Where<Person>(filterOfOrs);
列表过滤器=名称
.选择(名称=>
p=>p.Name==Name
).ToList();
表达式filterOfOrs=filters.orTheFiltersTogether();
query=query.Where(filterOfOrs);
LINQ不支持调用到实体:(@user288281如果是真的-sad.Expression树操作应该是.net级别的东西。树引用LinqToSql或LinqToEntities实例不会比使用int或字符串更影响您从中创建新树的能力。有人知道如何转换此示例,使其与实体框架一起工作。如何转换可以避免调用表达式吗?这一定是可能的,因为有了框架。它对我非常有用,因为我已经在研究Linq动态库来实现这一点。谢谢!做得不错,但不能使用Linq to实体和实体框架(6):LINQ to实体中不支持LINQ表达式节点类型“Invoke”。
public static Expression<Func<T, bool>> OrTheseFiltersTogether<T>(
this IEnumerable<Expression<Func<T, bool>>> filters)
{
Expression<Func<T, bool>> firstFilter = filters.FirstOrDefault();
if (firstFilter == null)
{
Expression<Func<T, bool>> alwaysTrue = x => true;
return alwaysTrue;
}
var body = firstFilter.Body;
var param = firstFilter.Parameters.ToArray();
foreach (var nextFilter in filters.Skip(1))
{
var nextBody = Expression.Invoke(nextFilter, param);
body = Expression.OrElse(body, nextBody);
}
Expression<Func<T, bool>> result = Expression.Lambda<Func<T, bool>>(body, param);
return result;
}
List<Expression<Func<Person, bool>>> filters = names
.Select<string, Expression<Func<Person, bool>>>(name =>
p => p.Name == name
).ToList();
Expression<Func<Person, bool>> filterOfOrs = filters.OrTheseFiltersTogether();
query = query.Where<Person>(filterOfOrs);