2010-12-08 10 views
12

Я ищу использовать LINQ сделать несколько, где условия на коллекции, подобныеДинамические LINQ ИЛИ Условия

IEnumerable<Object> items; 
items.Where(p => p.FirstName = "John"); 
items.Where(p => p.LastName = "Smith"); 

за исключением, а не имеющие многочисленные и условия (как в этом примере), я хотел бы иметь несколько условий ИЛИ.

EDIT К сожалению, уточнить, я не знаю, сколько из этих условий у меня будет так

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

не будет работать.

В принципе, вот что я пытаюсь сделать:

ответ

7

Это звучит, как белый список имен известно только во время выполнения. Возможно, попробуйте следующее:

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

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

подмигнули был очень полезен для меня, потому что я уже смотрел на Linq динамической библиотеки просто сделать это. Благодаря! – xleon 2015-06-24 01:16:12

13

Использование PredicateBuilder:

Предположим, вы хотите написать LINQ к SQL или Entity Framework запроса, который реализует поиск ключевых слов в стиле. Другими словами, запрос, который возвращает строки, в которых описание содержит некоторые или все из заданного набора ключевых слов ...

Идеальный подход для динамического создания лямбда-выражения дерева, которая выполняет -На предикат или ,

Из всего, что приведет вас к ручному построению деревьев выражений, потребность в динамических предикатах наиболее распространена в типичном бизнес-приложении. К счастью, можно написать набор простых и многоразовых методов расширения, которые радикально упрощают эту задачу. Это роль нашего PredicateBuilder класса ...

+0

Хорошая работа, но не работает с LINQ to Entities и Entity Framework (6): Тип выражения LINQ типа Invoke не поддерживается в LINQ to Entities. – 2016-12-13 10:51:20

10

Вы можете использовать .Union() возвращать результаты, которые удовлетворяют любые условия.

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

Это уступает с помощью оператора ||. Из вашего редактирования не ясно, почему это не сработает.

+0

Использование союза - определенно умный трюк! +1 для этого. – Steven 2010-12-08 19:05:09

0

Вы не можете сделать предложение Where динамическим, но вы можете динамически создавать выражение Лямбда, которое вы передаете ему. Создайте правильное значение Expression, скомпилируйте его и передайте полученное лямбда-выражение в качестве параметра в предложение Where.

EDIT:

Хорошо, кажется, что вы можете пропустить ту часть, где вы должны вручную создать выражение и может использовать PredicateBuilder для этого, как уже ответили AS-CII.

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

Invoke не поддерживается LINQ to Entities :( – yonexbat 2011-08-28 18:57:32

Смежные вопросы