Эквивалент «или» в лямбда-выражении Linq Where ()


91

Есть ли в Linq метод, с помощью которого вы можете создавать строки SQL, такие как «... where (a = 1) OR (a = 2)»?


4
Я предполагаю, что вы знаете, как использовать, ||и хотите чего-то динамичного, например a=a.where(hour=> hour<20); if(weekend) a=a.where(hour=> hour>6);. Вы можете заявить об этом более четко ...
Коби

Ответы:


189

Вы, безусловно, можете сделать это в предложении Where (метод расширения). Однако, если вам нужно динамически построить сложный запрос, вы можете использовать PredicateBuilder .

 var query = collection.Where( c => c.A == 1 || c.B == 2 );

Или используя PredicateBuilder

 var predicate = PredicateBuilder.False<Foo>();
 predicate = predicate.Or( f => f.A == 1 );
 if (allowB)
 {
    predicate = predicate.Or( f => f.B == 1 );
 }

 var query = collection.Where( predicate );

Это отлично сработало, так как мне нужно было построить свой Or в зависимости от значений входящих параметров - Отлично!
Марк

Очень круто. Жаль, что это не входит в стандартную функцию .NET.
maxp

1
Очень хорошая реализация, хотя, возможно, нельзя было заметить, что это работает только для C # 5+.
ThomasDonnelly

25

Вы можете использовать стандартные логические операторы .NET в своем единственном предложении where:

MyDataSource.Where(data => data.a == 'a' || data.a == 'b')

19

Вы используете те же операторы, что и в обычном C # ===> || для "или" && для "и" и т. д.

var something = from s in mycollection
                where s.something == 32 || 
                      s.somethingelse == 45 
                select s

1

в .Where()вызове используйте стандартный логический оператор "ИЛИ" ||.

var query = items.Where(item => (item == 1 || item == 2));

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


0

Если вы не знаете количество параметров, вы можете использовать это:

Пример данных

var parameters= new List<string>{"a","d"};
var sampledata = new Dictionary<string,string>();
    sampledata["a"] = "A";
    sampledata["b"] = "B";
    sampledata["c"] = "C";
    sampledata["d"] = "D";

Код

var query = sampledata.AsQueryable();
var firstItemKey = sampledata.FirstOrDefault().Key;
var queryresult= sampledata.Where(x => x.Key == firstItemKey).AsQueryable();
foreach (var parameter in parameters.Skip(1))
{
    queryresult=queryresult.Concat(query.Where(x => x.Key == parameter));
}
var result = queryresult.ToList();

-1

Теперь это встроено в .net, не уверен, что это было раньше. Учитывая существующий запрос Linq, вы можете добавить предложение where, которое принимает массив строк (SearchStrings), и проверить, соответствует ли какая-либо из них любому объекту в коллекции, которую вы ищете. Использование ToLower () просто гарантирует, что вы избегаете чувствительности к регистру в запросах SQL.

query.Where(i => SearchStrings.Any(s => i.ToLower().Contains(s.ToLower()));

Вы можете сделать то же самое для предиката 'and', сопоставив все слова в массиве с объектом коллекции.

query.Where(i => SearchStrings.All(s => i.ToLower().Contains(s.ToLower()));

В этом примере i коррелирует с каждым объектом в коллекции, а s коррелирует с каждой строкой в ​​массиве SearchStrings.


1
Обратите внимание, что «Any» не может быть переведено поставщиком EF и будет оцениваться локально, что приведет к полному сканированию таблицы и фильтрации в памяти.
Уэйд Би
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.