web-dev-qa-db-fra.com

Conversion d'un LEFT OUTER JOIN en Entity Framework

Voici une requête SQL que je veux convertir en EF4.3

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

Voici le meilleur LINQ que j'ai pu trouver:

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

Je sais que j'ai besoin de fusionner ma première jointure (entre autorisations et authentifications) dans, disons x et appliquons DefaultIfEmpty mais je ne peux pas déterminer la syntaxe.

EDIT: Image pour clarification: Data Model

Toute aide sera grandement appréciée. Cordialement.

13
Hassan Gulzar

La syntaxe de base pour une "jointure à gauche" dans Linq est la suivante:

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

Dans votre cas, je suis un peu confus parce que les relations d'entité que vous semblez utiliser dans votre Linq ne correspondent pas à celles qu'implique votre SQL; Les relations sont-elles ici zéro ou un, zéro ou plusieurs, un à un, etc.? Plus précisément, vous faites ceci:

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

mais votre SQL implique que "Authentification" est le parent avec zéro ou plusieurs enfants "Autorisation", et non l'inverse, ce qui ressemblerait davantage à:

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

Si vous pouvez nous donner une meilleure idée du modèle de données et des données que vous espérez en retirer, nous pourrons plus facilement expliquer à quoi ressemblerait cette requête dans Linq. En supposant que vos relations correspondent à ce qu'implique le code SQL, vous devriez pouvoir obtenir ce que vous voulez à l'aide des requêtes Linq suivantes:

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
Michael Edenfield

Etant donné les clés étrangères qui existent dans le diagramme de questions, qu’en est-il de ce genre de chose?

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