2011-01-31 4 views
5

To zapytanie zwraca identyfikator pracownika, imię i nazwisko, nazwę firmy, nazwę firmy i miasto firmy. Brakujący adres e-mail pracownika (adres e-mail przechowywany w tabeli EmployeeEmailAddress) i numery telefonów pracowników (numer telefonu zapisany w tabeli EmployeePhoneNumbers)..SelectMany() i pobieranie danych z więcej niż jednej pokrewnej tabeli

Potrzebowałem dodać .SelectMany(), aby uzyskać relację z firmą macierzystą i uzyskać dostęp do identyfikatora, nazwy i miasta firmy. Teraz jednak nie mam dostępu do żadnych właściwości, które nie zostały znalezione w tabeli PersonOrgMap. Nie mogę nawigować do innych stołów. Usunięcie .SelectMany() pozwala mi na nawigację do innych tabel, ale tracę dostęp do informacji o firmie macierzystej.

var employees = Contacts.Where(c => c.ContactAttributes 
.Any (ca => ca.AttributeID == 1153)) 
.SelectMany (x => x.ChildPersonOrgMaps) 
.Select (c => new { employeeId = c.Child.ContactID, 
      c.Child.FirstName, 
      c.Child.LastName, 
      companyId = c.ParentContactID, 
      c.Parent.OrganizationName, 
      c.Parent.City 
     } 
     ) 
.OrderBy (c =>c.LastName).ThenBy(x => x.FirstName) 
.Dump(); 

Odpowiedz

5

Tutaj naprawdę pomocne są wyrażenia zapytań. Jeśli uruchomić kwerendę tak:

from c in Contacts 
where c.ContactAttributes.Any (ca => ca.AttributeID == 1153)) 
from om in c.ChildPersonOrgMaps 
... 

będziesz miał dostęp do obu c i om zmiennych później w zapytaniu. C# tłumaczy to na wywołanie SelectMany, wybierając tymczasowy anonimowy typ, który "przenosi" oryginalną zmienną. Najlepszym sposobem, aby to zobaczyć, jest napisanie zapytania jako wyrażenia zapytania w LINQPad, następnie spójrz na zakładkę lambda, aby zobaczyć tłumaczenie na płynną składnię.

+4

+1 do bezwstydnej wtyczki LINQPad ;-) Bardzo fajny produkt! – DenaliHardtail

0

Zgadzam się z Joe Albahari - użyj składni zapytania. Jest to jedyna rzecz (o której mi wiadomo), że można zrobić z zapytaniem, którego nie można z użyciem składni metody.

Możesz spróbować wybrać anonimowy typ zawierający obiekty nadrzędne i podrzędne, ale nie sądzę, że EF będzie się to bardzo podobało.

var employees = Contacts.Where(c => c.ContactAttributes 
.Any (ca => ca.AttributeID == 1153)) 
.SelectMany (x => new { Parent = x, Child = x.ChildPersonOrgMaps }) 
// etc 
16

Jeśli jesteś zapalonym o składni metody, to nie przeciążenia na SelectMany(), która daje również dostęp zarówno do „źródła” oraz obiektów „Wynik”:

.SelectMany(x => x.ChildPersonOrgMaps, (x, c) => new { x, c }) 
.Select(xc => new 
{ 
    xc.x.Attribute1, 
    xc.x.Attribute2, 
    xc.c.Child.Attribute3, 
    xc.c.Attribute4 
});