Mam dwie kolekcje, które mają właściwości Email
w obu kolekcjach. Muszę uzyskać listę elementów na pierwszej liście, których Email
nie ma na drugiej liście. W przypadku SQL użyłbym po prostu „nie w”, ale nie znam odpowiednika w LINQ. Jak to się robi?
Do tej pory mam połączenie, jak ...
var matches = from item1 in list1
join item2 in list2 on item1.Email equals item2.Email
select new { Email = list1.Email };
Ale nie mogę dołączyć, ponieważ potrzebuję różnicy, a połączenie się nie powiedzie. Potrzebuję sposobu, w jaki wierzę, zawiera lub istnieje. Po prostu nie znalazłem jeszcze takiego przykładu.
Odpowiedzi:
Nie wiem czy to ci pomoże, ale ...
od klauzuli NOT IN w LINQ do SQL autorstwa Marco Russo
źródło
Chcesz operatora z wyjątkiem.
Lepsze wyjaśnienie tutaj: https://docs.microsoft.com/archive/blogs/charlie/linq-farm-more-on-set-operators
UWAGA: Ta technika działa najlepiej tylko w przypadku typów pierwotnych, ponieważ należy zaimplementować IEqualityComparer, aby użyć
Except
metody ze złożonymi typami.źródło
list1.Select(item => new { Property1 = item.Property1, Property2 = item.Property2 }).Except(list2.Select( item => new { Property1 = item.Property1, Property2 = item.Property2 }));
jest to szczególnie przydatne, gdy określasz równość, oceniając tylko zestaw wartości typu złożonego.IEquatityComparor<T,T>
ani zastępować metod porównywania obiektów wLinqToSql
scenariuszu; ponieważ zapytanie będzie reprezentowane jako / skompilowane do / wyrażone jako SQL; dlatego wartości będą sprawdzane, a nie odwołanie do obiektu.except
I udało mi się przyspieszyć zapytanie LINQ z 8-10 sekund do pół sekundyDla osób, które zaczynają od grupy obiektów w pamięci i wykonują zapytania do bazy danych, uważam, że to najlepszy sposób:
To tworzy ładną
WHERE ... IN (...)
klauzulę w SQL.źródło
źródło
Możesz użyć kombinacji Where i Any do znalezienia nie w:
źródło
Możesz wziąć obie kolekcje na dwóch różnych listach, powiedzmy list1 i list2.
Więc po prostu napisz
To zadziała.
źródło
W przypadku, gdy używa się ADO.NET Entity Framework , rozwiązanie EchoStorm również działa idealnie. Ale zajęło mi to kilka minut, aby owinąć wokół niego głowę. Zakładając, że masz kontekst bazy danych, dc i chcesz znaleźć wiersze w tabeli x niepołączone w tabeli y, pełna odpowiedź brzmi:
W odpowiedzi na komentarz Andy'ego tak, w zapytaniu LINQ można mieć dwa z nich. Oto kompletny przykład działania z wykorzystaniem list. Każda klasa, Foo i Bar, ma identyfikator. Foo ma odniesienie do Bar za pomocą „klucza obcego” za pośrednictwem Foo.BarId. Program wybiera wszystkie Foo niepowiązane z odpowiednim paskiem.
źródło
źródło
Można również użyć
All()
źródło
Chociaż
Except
jest częścią odpowiedzi, to nie jest cała odpowiedź. DomyślnieExcept
(podobnie jak kilku operatorów LINQ) dokonuje porównania referencji dla typów referencji. Aby porównać według wartości w obiektach, musiszIEquatable<T>
w swoim typie lubEquals
iGetHashCode
w swoim typie, lubIEqualityComparer<T>
dla danego typuźródło
Przykład użycia listy int dla uproszczenia.
źródło
Dla każdego, kto chce również używać
IN
operatora podobnego do SQL w C #, pobierz ten pakiet:Ma
In
iNotIn
metody:Nawet ty możesz tego użyć w ten sposób
źródło
Dziękuję, Brett. Twoja sugestia też mi pomogła. Miałem listę obiektów i chciałem ją przefiltrować za pomocą innej listy obiektów. Dzięki jeszcze raz....
Jeśli ktoś potrzebuje, spójrz na mój przykładowy kod:
źródło
Nie testowałem tego za pomocą LINQ dla podmiotów :
Alternatywnie:
źródło
Czy nie możesz wykonać zewnętrznego połączenia, wybierając elementy z pierwszej listy tylko wtedy, gdy grupa jest pusta? Coś jak:
Nie jestem pewien, czy działałoby to w jakikolwiek efektywny sposób w ramach Entity.
źródło
Alternatywnie możesz to zrobić w następujący sposób:
źródło