动态LINQ或条件

动态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); } 听起来您的白

我希望使用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);
}

听起来您的白名单只有在运行时才知道。也许可以试试这个:

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);