动态LINQ OR条件

时间:2010-12-08 18:45:59

标签: linq

我希望使用LINQ在类似于

的集合上执行多个条件
IEnumerable<Object> items;
items.Where(p => p.FirstName = "John");
items.Where(p => p.LastName = "Smith");

除了没有多个AND条件(如本例所示)之外,我想要有多个OR条件。

修改 对不起,澄清一下,我不知道有多少这样的条件,所以

items.Where(p => p.FirstName = "John" || p => p.LastName = "Smith")

无效。

基本上,这就是我要做的事情:

foreach(var name in names)
{
    items = items.Where(p => p.Name == name);
}

5 个答案:

答案 0 :(得分:13)

使用PredicateBuilder

  

假设您要编写实现关键字样式搜索的LINQ to SQL或Entity Framework查询。换句话说,一个返回描述包含一些或全部给定关键字集的行的查询......

     

理想的方法是动态构造一个执行基于的谓词的lambda表达式树。

     

在推动您手动构建表达式树的所有事情中,动态谓词的需求是典型业务应用程序中最常见的。幸运的是,可以编写一组简单且可重用的扩展方法,从根本上简化此任务。这是我们的 PredicateBuilder 类...

的作用

答案 1 :(得分:10)

您可以使用.Union()返回满足任何条件的结果。

var results = items.Where(p => p.FirstName == "John")
     .Union(items.Where(p => p.LastName == "Smith"));

这不如使用||运算符。从您的编辑中不清楚为什么这不起作用。

答案 2 :(得分:8)

听起来你的名字白名单只在运行时才知道。也许试试这个:

string[] names = new string[] {"John", "foo", "bar"};

var matching = items.Where(x => names.Contains(x.Name));

答案 3 :(得分:2)

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

答案 4 :(得分:0)

您无法使Where子句动态化,但您可以动态创建传递给它的Lambda Expression。创建正确的Expression,编译它并将生成的lambda表达式作为参数传递给Where子句。

修改

好的,似乎您可以跳过必须手动创建表达式的部分,并可以使用PredicateBuilder,因为AS-CII已经回答过了。