Odpowiednik „lub” w wyrażeniu lambda Linq Where ()


91

Czy w Linq jest metoda, której można użyć do tworzenia łańcuchów SQL, takich jak „... gdzie (a = 1) LUB (a = 2)”?


4
Zakładam, że wiesz, jak używać ||i chcesz czegoś dynamicznego, na przykład a=a.where(hour=> hour<20); if(weekend) a=a.where(hour=> hour>6);. Możesz chcieć to wyraźniej powiedzieć ...
Kobi

Odpowiedzi:


189

Z pewnością możesz to zrobić w ramach klauzuli Where (metoda rozszerzająca). Jeśli jednak potrzebujesz dynamicznie zbudować złożone zapytanie, możesz użyć PredicateBuilder .

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

Lub używając 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 );

To działało świetnie, ponieważ musiałem zbudować mój lub w zależności od wartości parametrów przychodzących - Super!
Mark

Bardzo fajny. Szkoda, że ​​nie jest to standardowo uwzględnione jako funkcja w .NET.
maxp

1
Bardzo ładna implementacja, chociaż można nie zauważyć, działa to tylko dla C # 5+.
Thomas.Donnelly

25

Możesz użyć standardowych operatorów boolowskich .NET w swojej pojedynczej klauzuli where:

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

19

Używasz tych samych operatorów, co w normalnym C # ===> || zamiast „lub„ && for ”i„ itp.

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

1

w .Where()zaproszeniu użyć standardowego Boolean „lub” operatora, ||.

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

Wszystko, co robi wywołanie Where, to porównanie logiczne wszystkiego, co chcesz, więc możesz wypełnić je dowolną logiką warunkową.


0

Jeśli nie znasz liczby parametrów, możesz użyć tego:

Przykładowe dane

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

Kod

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

Jest to teraz wbudowane w .net, nie jestem pewien, czy wcześniej nie było. Biorąc pod uwagę istniejące zapytanie Linq, możesz dodać klauzulę where, która pobiera tablicę ciągów (SearchStrings) i sprawdzić, czy którykolwiek z nich pasuje do dowolnego obiektu w kolekcji, którą przeszukujesz. Użycie ToLower () zapewnia tylko unikanie rozróżniania wielkości liter w zapytaniach SQL.

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

Możesz zrobić to samo dla predykatu „i”, dopasowując wszystkie słowa w tablicy do obiektu kolekcji.

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

W tym przykładzie i koreluje z każdym obiektem w kolekcji, a s koreluje z każdym ciągiem w tablicy SearchStrings.


1
Należy zauważyć, że „Any” nie może zostać przetłumaczone przez dostawcę EF i zostanie ocenione lokalnie, co spowoduje pełne skanowanie tabeli i filtrowanie w pamięci.
Wade Bee
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.