Hice una pregunta anterior sobre why left joins in Linq can't use defined relationships; hasta la fecha no he recibido una respuesta satisfactoria.¿Cómo te unes a Linq si hay más de un campo en la unión?
Ahora, en una pista paralela, he aceptado que necesito usar la palabra clave join
como si no hubiera relación definida entre mis objetos, y estoy tratando de encontrar la manera de expresar mi consulta en Linq. El problema es que es un conglomerado de combinaciones a la izquierda entre varias tablas, con múltiples campos involucrados en la unión. No hay manera de simplificar esto, así que aquí está el SQL en todo su esplendor desenmascarado:
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, si ayuda a entender lo que estoy tratando de hacer: Estoy tratando de identificar si hay alguna . TreatmentPlanDetail
registros de este Patient
donde el Payer
autorizar requiere una receta para este ServiceType
, pero o bien no hay ServicePerscription
registro, o ha expirado)
Ahora, esto es lo que se ve mi C# código como:
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 };
Vaya, no compila! Por alguna razón (me encantaría una explicación) ¡No puedo usar ese booleano literal dentro de la equijoin! Bien, lo dejaré fuera, y filtrar el "RequiresPrescription" cosas después ...
...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID }
...
... y ahora compila - pero cuando corro, me sale un "Referencia a objeto no establecida" excepción en esta línea. DUH! ¡Por supuesto que hay un nulo allí! ¿De qué otra forma se supone que debes hacer una comparación con una combinación de la izquierda, si no puedes referenciar el objeto del lado derecho, que podría ser nula?
Entonces, ¿cómo se supone que debe hacer una combinación izquierda usando múltiples campos?
Para el problema booleano, ¿no podría ser un problema de nomenclatura (nada coincide con "RxReq" en el lado derecho y nada coincide con "RequiresPrescription" en el lado izquierdo)? Intente nombrar el booleano "RequiresPrescription" o nombre específicamente el pstr.RequiresPrescription "RxReq" del lado derecho. –