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?
OriginalL'auteur Shaul Behr | 2009-07-07
Vous devez vous connecter pour publier un commentaire.
Je pense que vous devez utiliser le
into
de mots clés et de résoudre les cas d'enfants disparus DefaultIfEmpty() après le rejoindre, pas avant:LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
est probablement tournant jusqu'à une valeur nulle car la DataTable retourné contient pas de lignes, donc à l'origine de votre exception. Noter l'intégralité de l'instruction après lain
sera exécutée avant la sélection en elle, qui n'est pas le comportement souhaité. Vous voulez que les lignes correspondantes ou null si aucune correspondance n'lignes existent.Pour le booléen problème, c'est 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 les
true
"RequiresPrescription" comme je l'ai ci-dessus (ou un nom du côté droit dupstr.RequiresPrescription
"RxReq").OriginalL'auteur lc.