Piszę dużo takiego kodu, aby wybrać jeden pasujący element
var item = (from x in Items where x.Id == 123 select x).First();
Czy jest na to czystszy sposób, czy jest to tak zwięzłe, jak zamierzam?
EDYCJA: Powinienem był powiedzieć „Czystszy sposób korzystania ze składni linq”. Byłem już świadomy składni lambda i zaczyna wyglądać, że to właściwie jedyny sposób. Dostałem jednak przydatne informacje, więc dziękuję wszystkim, którzy odpowiedzieli.
Single()
iSingleOrDefault()
JEŚLI wiem, że dane są już unikalne (na przykład z bazy danych, która ma to ograniczenie itp.), PonieważSingle()
zmusza ją do przeszukania reszty listy w celu znalezienia możliwego duplikatu, ale to ja. Jeśli w tym momencie musisz narzucić swoją wyjątkowość, użyjSingle()
rodziny, jeśli nie, użyjFirst()
rodziny.Odpowiedzi:
W zależności od tego, jak bardzo podoba Ci się składnia zapytania linq, możesz użyć metod rozszerzających bezpośrednio, takich jak:
A jeśli nie chcesz zgłaszać błędu, jeśli lista jest pusta, użyj funkcji,
FirstOrDefault
która zwraca domyślną wartość dla typu elementu (null
dla typów referencyjnych):Single()
iSingleOrDefault()
może być również używany, ale jeśli czytasz z bazy danych lub czegoś, co już gwarantuje wyjątkowość, nie przejmowałbym się, ponieważ musi skanować listę, aby sprawdzić, czy są jakieś duplikaty i wyrzuty.First()
iFirstOrDefault()
zatrzymają się na pierwszym meczu, dzięki czemu są bardziej wydajni.Z rodziny
First()
iSingle()
, oto gdzie rzucają:First()
- wyrzuca, jeśli jest pusty / nie znaleziony, nie rzuca, jeśli jest zduplikowanyFirstOrDefault()
- zwraca wartość domyślną, jeśli jest pusta / nie znaleziono, nie rzuca, jeśli jest zduplikowanaSingle()
- wyrzuca, jeśli jest pusty / nie znaleziono, wyrzuca, jeśli istnieje duplikatSingleOrDefault()
- zwraca wartość domyślną, jeśli jest pusta / nie znaleziono, zgłasza, jeśli istnieje duplikatźródło
i.Id == 123
FirstOrDefault lub SingleOrDefault mogą być przydatne, w zależności od scenariusza i tego, czy chcesz obsłużyć zero lub więcej dopasowań:
Nie wiem, jak to działa w zapytaniu linq „from”, ale w składni lambda wygląda to tak:
źródło
Oto preferowane metody:
Lub
źródło
Aby ułatwić komuś życie, zapytanie linq z wyrażeniem lambda
powoduje zapytanie SQL zawierające
select top (1)
w sobie.źródło
Można to lepiej sprowadzić do tego.
var item = Items.First(x => x.Id == 123);
Twoje zapytanie zbiera obecnie wszystkie wyniki (a może być więcej niż jeden) w ramach wyliczenia, a następnie pobiera pierwszy z tego zestawu, wykonując więcej pracy niż to konieczne.
Single / SingleOrDefault są warte zachodu, ale tylko wtedy, gdy chcesz wykonać iterację przez całą kolekcję i sprawdzić, czy dopasowanie jest unikalne, oprócz wybrania tego dopasowania. First / FirstOrDefault po prostu weźmie pierwsze dopasowanie i opuści, niezależnie od tego, ile faktycznie duplikatów istnieje.
źródło
Możesz użyć składni metody rozszerzenia:
Poza tym nie jestem pewien, o ile bardziej zwięźle można uzyskać bez pisania własnych wyspecjalizowanych metod rozszerzających „First” i „FirstOrDefault”.
źródło
Where
w przeciwieństwie do tegoSelect
, co już zostało powiedziane, ale ta odpowiedź jest nieprawidłowa. Wybierz w c # zmienia wyniki na IEnumerable <bool>, więc otrzymujeszbool
dla pierwszego elementux.Id == 123
Powiem ci, co mi pomogło:
Mój identyfikator to wiersz, który chcę zapytać, w tym przypadku otrzymałem go z radGrid, a następnie użyłem go do zapytania, ale to zapytanie zwraca wiersz, a następnie możesz przypisać wartości otrzymane z zapytania do pola tekstowego lub cokolwiek , Musiałem je przypisać do pola tekstowego.
źródło