Comment avez-vous jointure gauche dans Linq si il n'y a plus d'un champ dans la jointure?

J'ai posé une question plus haut à propos de pourquoi la gauche s'unit en Linq ne pouvez pas utiliser de relations définies; à ce jour, je n'ai pas obtenu de réponse satisfaisante.

Maintenant, sur une voie parallèle, j'ai accepté que j'ai besoin d'utiliser la join mot-clé comme s'il n'y avait pas de relation définie entre mes objets, et je suis en train de travailler sur la façon d'exprimer ma requête Linq. La difficulté est, il est un conglomérat de gauche des jointures entre plusieurs tables, avec de multiples champs impliqués dans la jointure. Il n'y a pas moyen de simplifier ce, alors, voici le code SQL dans tous ses démasqué gloire:

select *
from TreatmentPlan tp
join TreatmentPlanDetail tpd on tpd.TreatmentPlanID = tp.ID
join TreatmentAuthorization auth on auth.TreatmentPlanDetailID = tpd.ID
left join PatientServicePrescription rx on tpd.ServiceTypeID = rx.ServiceTypeID
left join PayerServiceTypeRules pstr on auth.PayerID = pstr.PayerID and tpd.ServiceTypeID = pstr.ServiceTypeID and pstr.RequiresPrescription = 1
where tp.PatientID = @PatientID

(Pour info, si ça aide à comprendre ce que je suis en train de faire: je suis en train de déterminer s'il existe des TreatmentPlanDetail des records pour ce Patient où l'autorisant Payer nécessite une ordonnance pour ce ServiceType, mais il n'y a pas ServicePerscription dossier, ou a expiré.)

Maintenant, voici ce que mon code C# ressemble:

var q = from tp in TreatmentPlans
        from tpd in tp.Details
        from auth in tpd.Authorizations
        join rx in ServicePrescriptions.DefaultIfEmpty() on tpd.ServiceTypeID equals rx.ServiceTypeID
        //from pstr in auth.Payer.ServiceTypeRules.DefaultIfEmpty() -- very frustrating that this doesn't work!!
        join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
        on new { auth.PayerID, tpd.ServiceTypeID, RxReq = (bool)true } equals new { pstr.PayerID, pstr.ServiceTypeID, pstr.RequiresPrescription }
        select new { Payer = auth.Payer, Prescription = rx, TreatmentPlanDetail = tpd, Rules = pstr };

Oups, ne compile pas! Pour une raison quelconque (j'aimerais une explication, je ne peux utiliser que les littéraux booléens à l'intérieur de l'équi-jointure! Bien, je vais le laisser, et de filtrer les "RequiresPrescription" tout ça plus tard...

...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID }
...

... et maintenant ça compile mais quand je le lance, j'obtiens un "Objet de référence non définie" l'exception " sur cette ligne. DUH! Bien sûr, il y a une valeur null dans il y! Sinon, comment êtes-vous censé effectuer une comparaison avec un left join, si vous n'êtes pas autorisé à référencer l'objet sur le côté droit, qui pourrait éventuellement être nulle?

Alors, comment êtes-vous censé faire une jointure gauche à l'aide de plusieurs champs?

Pour le booléen problème, ne pourrait-elle pas être un problème de nom (rien ne correspond à "RxReq" sur le côté droit et rien ne correspond à "RequiresPrescription" sur le côté gauche)? Essayez de nommer le booléen "RequiresPrescription" ou, plus spécifiquement, nom le côté droit de la pstr.RequiresPrescription "RxReq".

OriginalL'auteur Shaul Behr | 2009-07-07