webentwicklung-frage-antwort-db.com.de

Konvertieren eines LEFT OUTER JOIN in ein Entity Framework

Hier ist eine SQL-Abfrage, die ich in EF4.3 konvertieren möchte

        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");

Hier ist der beste LINQ, den ich finden konnte:

        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
            };

Ich weiß, dass ich meinen ersten Join (zwischen Authorizations & Authentications) zusammenführen muss, sagen wir x und wenden DefaultIfEmpty an, kann aber die Syntax nicht erkennen.

EDIT: Bild zur Verdeutlichung: Data Model

Jede Hilfe wird sehr geschätzt. Grüße.

13
Hassan Gulzar

Die grundlegende Syntax für einen "left join" in Linq sieht folgendermaßen aus:

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
};

In Ihrem Fall bin ich ein wenig verwirrt, weil die Entitätsbeziehungen, die Sie in Ihrem Linq zu verwenden scheinen, nicht mit den von Ihrem SQL implizierten übereinstimmen. Sind die Beziehungen hier null oder eins, null oder viele, eins zu eins usw.? Im Einzelnen machen Sie Folgendes:

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

ihre SQL impliziert jedoch, dass "Authentication" hier das übergeordnete Element mit null oder mehr "Authorization" -Kindern ist, und nicht umgekehrt.

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

Wenn Sie uns eine bessere Vorstellung vom Datenmodell und den Daten geben können, von denen Sie erwarten, dass sie daraus resultieren, können wir leichter erklären, wie diese Abfrage in Linq aussehen würde. Angenommen, Ihre Beziehungen stimmen mit dem überein, was SQL impliziert, sollten Sie in der Lage sein, mit den folgenden Linq-Abfragen das zu erhalten, was Sie wollen:

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 
             };
38

Wie steht es mit den Fremdschlüsseln im Fragendiagramm?

var query = from a in context.Authentications
            select new
            {
                a.AuthenticationID,
                a.Username,
                a.Authorisations.Permissions ?? false,
                a.Authorisations.Organisations.OrganisationIdentifier ?? 0
                a.Authorisations.Organisations.OrganisationID ?? 0
            };
0
Graham Laight