“Або” еквівалент у виразі Linq Where () лямбда


91

Чи існує в Linq метод, де ви можете використовувати для побудови рядків SQL, наприклад "... де (a = 1) АБО (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 );

Це чудово працювало, оскільки мені потрібно було побудувати свій Або, залежно від значень вхідних параметрів - Чудово!
Марк

Дуже круто. Шкода, що це не є стандартною функцією всередині .NET.
maxp

1
Дуже приємна реалізація, хоча, можливо, і не було зазначено, це працює лише для C # 5+.
Томас. Доннеллі

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()виклику використовувати стандартний Boolean «або» оператора, ||.

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

Ви можете зробити те ж саме для предиката 'і', зіставивши всі слова в масиві з об'єктом колекції.

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

У цьому прикладі я корелює з кожним об'єктом у колекції, а s корелює з кожним рядком у масиві SearchStrings.


1
Зверніть увагу, що "Будь-який" не може бути перекладений постачальником EF, і він буде оцінений локально, що призведе до повного сканування таблиці та фільтрації в пам'яті.
Wade Bee,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.