2012-02-29 17 views
13

Oto zapytań SQL chcę przekonwertować do EF4.3Konwersja LEFT OUTER JOIN Entity Framework

 command = database.GetSqlStringCommand(@" 
           select 
            H.AUTHENTICATION_ID, 
            USERNAME, 
            PERMISSIONS, 
            ORGANIZATION_IDENTIFIER, 
            O.ORGANIZATION_ID 
           from 
            AUTHENTICATION H 
             left join [AUTHORIZATION] T on H.AUTHENTICATION_ID=T.AUTHENTICATION_ID 
             join ORGANIZATION O on O.ORGANIZATION_ID = T.ORGANIZATION_ID 
           order by H.AUTHENTICATION_ID"); 

Oto najlepszy LINQ mogę wymyślić:

 var query = from h in context.Authentications 
      join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId 
      join o in context.Organizations on t.Organizations.OrganizationId equals o.OrganizationId 
      orderby 
      h.AuthenticationId 
      select new 
      { AUTHENTICATION_ID = (Int16?)h.AuthenticationId, 
       h.Username, 
       t.Permissions, 
       o.OrganizationIdentifier, 
       OrganizationID = (Int16?)o.OrganizationId 
      }; 

I wiem, że muszę połączyć moje pierwsze sprzężenie (między autoryzacjami & Uwierzytelnianie) w, powiedzmy x i zastosuj DefaultIfEmpty, ale nie mogę odczytać składni.

EDIT: Obraz dla wyjaśnienia: Data Model

Każda pomoc będzie bardzo mile widziane. Pozdrowienia.

Odpowiedz

33

Podstawowa składnia dla „left join” w LINQ jest tak:

from x in table1 
join y in table2 on x.id equals y.id into jointable 
from z in jointable.DefaultIfEmpty() 
select new 
{ 
    x.Field1, 
    x.Field2, 
    x.Field3, 
    Field4 = z == null ? 0 : z.Field4 
}; 

W twoim przypadku, jestem trochę zdezorientowany, bo relacje jednostka wydaje się być używany w Linq don” t pasują do tych sugerowanych przez Twój SQL; czy są tu relacje zero-lub-one, zero-or-many, one-to-one, etc? Konkretnie, to robisz:

from h in context.Authentications 
join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId 

ale Twój SQL oznacza, że ​​„Autoryzacja” jest rodzicem tu z zerowym lub-bardziej „zezwolenie” dzieci, nie na odwrót, co byłoby więcej takich jak:

from h in context.Authentications 
from t in h.Authorizations.DefaultIfEmpty() 

Jeśli możesz dać nam lepsze pojęcie o modelu danych i jakie dane można oczekiwać, aby wydostać się z niego możemy łatwiej wyjaśnić, jak to będzie wyglądać w kwerendy Linq. Zakładając, że Twoje relacje pasuje co jest dorozumiany przez SQL, powinieneś być w stanie uzyskać to, czego chcą przy użyciu następujących zapytań LINQ:

var query = from h in context.Authentications 
      from t in h.Authorizations.DefaultIfEmpty() 
      select new 
      { 
       h.AuthenticationId, 
       h.Username, 
       Permissions = t == null ? null : t.Permissions, 
       Organizations = t == null ? new EntitySet<Organization>() : t.Organizations 
      }; 

var query2 = from x in query 
      from o in x.organizations.DefaultIfEmpty() 
      select new 
      { 
       AUTHENTICATION_ID = (short?)x.AuthenticationId, 
       x.Username, 
       x.Permissions, 
       OrganizationIdentifier = o == null ? null : o.OrganizationIdentifier, 
       OrganizationID = o == null ? (short?)null : o.OrganizationID 
      }; 
+0

Dzięki za szczegóły. Załączam obraz do mojego pytania. Prosimy o sprawdzenie, czy to wyjaśnia moją sytuację. Dzięki za odpowiedź. Bardzo doceniane. – DoomerDGR8

+1

Biorąc pod uwagę obraz, myślę, że LINQ, który zamieściłem, zadziała. Otrzymasz wszystko od tabeli Uwierzytelnień, a także wszelkie pasujące autoryzacje (jeśli takie istnieją) dla tych Uwierzytelnień oraz wszelkie pasujące Organizacje dla tych Uwierzytelnień. –

+1

Jedna drobna aktualizacja, której możesz potrzebować: jak napisałem, moja odpowiedź zwróci autoryzacje, które nie mają pasujących rekordów organizacji - drugie połączenie lewostronne zamiast wewnętrznego. W zależności od modelu danych, który może, ale nie musi, musisz się martwić; jeśli to jest problem, daj mi znać. –

-3

poszedł do przodu i przeniósł całą zapytanie do procedury przechowywanej w bazie danych. Rozwiązuje to problem, unikając LINQ i ObjectBuilder w pierwszej kolejności.

+3

Oczywiste awarie najgorszego przypadku, nie jest to przydatna odpowiedź. –

+0

Dla mnie jest to oczywisty przypadek użycia odpowiedniego narzędzia do pracy. – Vaiden

+2

Brzmi bardziej, gdy trzymasz młotek, wszystko, co widzisz, przypomina gwóźdź. –