Zadałem pytanie wcześniej o why left joins in Linq can't use defined relationships; do tej pory nie otrzymałem satysfakcjonującej odpowiedzi.Jak odszedłeś dołączyć do Linq, jeśli w złączeniu jest więcej niż jedno pole?
Teraz, na równoległym torze, zgodziłem się, że muszę używać słowa kluczowego join
, jak gdyby nie było żadnej relacji między moimi obiektami i próbuję wyjaśnić, jak wyrazić moje zapytanie w Linq. Problem polega na tym, że jest to konglomerat lewych połączeń między wieloma tabelami, z wieloma polami związanymi z łączeniem. Nie ma mowy o uproszczenie tego, więc tutaj jest SQL w całej swej zdemaskowany chwały
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
(FYI, jeśli pomaga zrozumieć, co próbuję zrobić: Próbuję ustalić, czy istnieją . TreatmentPlanDetail
zapisy dla tego Patient
gdzie zezwalający Payer
wymaga recepty dla tego ServiceType
, ale nie ma albo nie ServicePerscription
rekord, albo wygasło)
teraz, oto co moim kod C# wygląda następująco:
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 };
Ups, nie kompiluje! Z jakiegoś powodu (chciałbym wyjaśnienia) nie mogę użyć tego dosłownie boolean wewnątrz equijoin! Dobrze, zostawię go i odfiltrować „RequiresPrescription” rzeczy później ...
...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID }
...
... a teraz kompiluje - ale gdy uruchomię, otrzymuję „Odwołanie do obiektu nie ustawiony” wyjątek w tej linii. DUH! Oczywiście jest tam zerowy! Jak inaczej należy wykonać porównanie z lewostronnym, jeśli nie wolno ci odwoływać się do obiektu po prawej stronie, który może być pusty?
Jak zatem wykonać lewe połączenie przy użyciu wielu pól?
Dla problemu boolowskiego, czy nie może to być problem z nazewnictwem (nic nie pasuje do "RxReq" po prawej stronie i nic nie pasuje do "RequestsPrescription" po lewej stronie)? Spróbuj nazywać boolean "RequestsPress" lub konkretnie nazwij prawą stronę pstr.RequiresPrescription "RxReq". –