2010-10-04 13 views
18

Szukałem w zapytaniu współpracownicy LINQ pokazano poniżej (kwerenda wykonuje poprawnie):LINQ „do” zamieszania kluczowego

from ea in EquipmentApplication 
join erl in EquipmentRoutingLocation on ea.EquipmentID equals erl.EquipmentID into erlWithNulls 

from erlAll in erlWithNulls.DefaultIfEmpty() 
join rl in RoutingLocation on erlAll.RoutingLocationID equals rl.RoutingLocationID into rlWithNulls 

from rlAll in rlWithNulls.DefaultIfEmpty() 
where ea.Equipment.Master_Cell.Area.Unit.UnitID == 1160 
select new { ea.Equipment, ea.ApplicationFriendlyName, rlAll } 

Jestem zdezorientowany, dlaczego to działa. Rozumiem (być może niepoprawnie), że słowo kluczowe "do" kończy bieżący zakres/kontekst (a wszelkie zmienne utworzone są poza zakresem) i tworzy nowe. Jeśli to prawda, dlaczego zmienna "ea" nadal znajduje się w zakresie w ostatniej części zapytania?

Odpowiedz

30

Po użyciu ze słowem kluczowym select, into zakończy zakres.
W przypadku użycia ze słowem kluczowym join, into doda zmienną zawierającą wszystkie pasujące elementy z łączenia. (To się nazywa Group Join)

+0

więc podczas korzystania z wielu sprzężeń używacie „do” klauzuli i dołącz kolejną frazę, że „zmienna”, że właśnie dodane? – Jacques

19

"do" ma dwa różne znaczenia:

  • w A join klauzuli zmienia tłumaczenie z użyciem Join do GroupJoin. Oznacza to, że zamiast uzyskiwania jednego wyniku na pasującą parę, otrzymuje się jeden wynik dla każdego elementu oryginalnej sekwencji, a ten wynik zawiera klucz i wszystkie wyniki z drugiej sekwencji, jako grupę. Aby uzyskać więcej informacji, zobacz Enumerable.GroupJoin
  • W postaci lub group...by staje się to query continuation, skutecznie uruchamiając nowe zapytanie z wynikami starego w nowej zmiennej zakresu.
+0

Link "Kontynuacja zapytania" nie jest już ważny! – Celdor

+0

@ZikO: Naprawiono, dziękuję. –

12

Aby dodać do tego, co już zostało powiedziane, chciałabym wykazać różnicę w strukturze obiektu produkowanego przez w porównaniu bez:

var q = 
    from c in categories 
    join p in products on c equals p.Category into ps 
    select new { Category = c, Products = ps }; 

Tworzy wykres obiektu:

Category 1, Products: 
    Product 1 
    Product 2 
Category 2, Products: 
    Product 3 
    Product 4 

W tym przypadku q zawiera tylko 2 elementy, dwie kategorie.

Bez się, można uzyskać bardziej tradycyjny przyłączyć że spłaszcza relacje tworząc wszystkie możliwe kombinacje:

var q = 
    from c in categories 
    join p in products on c equals p.Category 
    select new { Category = c, Product = p }; 

Category 1, Product 1 
Category 1, Product 2 
Category 2, Product 3 
Category 2, Product 4 

Zauważ, że teraz q zawiera 4 pozycje.

Update, myślę:

var q = 
    from c in categories 
    join p in products on c equals p.Category into ps 
    select new { Category = c, Products = ps.Select(x=> x.Id) }; 
+0

W pierwszym przykładzie, zamiast wybierać cały produkt 1, 2 i 3, 4. Jak wybrać identyfikatory lub produkt 1, 2 i 3, 4? –

+0

@RayCheng Nie mam tutaj konfiguracji do testowania, ale opublikowałem inny fragment kodu, który może działać, może być konieczne dodanie ToList 'ps.Select (---) .ToList()' – AaronLS