![](/img/trans.png)
[英]How do I join more than one files, in a Linq (C#) where one of the joins is a left join
[英]How do you left join in Linq if there is more than one field in the join?
我之前問了一個問題, 為什么Linq中的左連接不能使用已定義的關系 ; 到目前為止,我還沒有得到滿意的答復。
現在,在並行軌道上,我已經接受了我需要使用join
關鍵字,好像我的對象之間沒有定義關系,我正在嘗試找出如何在Linq中表達我的查詢。 麻煩的是,它是多個表之間左連接的集合體,連接中涉及多個字段。 沒有辦法簡化這個,所以這里是SQL所有未被掩蓋的榮耀:
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
(僅供參考,如果它有助於理解我正在嘗試做什么:我正在嘗試確定該Patient
是否有任何TreatmentPlanDetail
記錄,其中授權Payer
需要處方此ServiceType
,但是沒有ServicePerscription
記錄,或者它已經過期了。)
現在,這是我的C#代碼:
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 };
哎呀,不編譯! 出於某種原因(我喜歡解釋)我不能在equijoin中使用那個文字布爾值! 好吧,我會把它留下來,然后過濾掉“RequiresPrescription”的東西......
...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID }
...
...現在它編譯 - 但是當我運行時,我在這一行上得到一個“對象引用未設置”異常。 DUH! 當然那里有空! 如果你不允許引用右側的對象,那么你應該如何與左連接進行比較,這可能是空的?
那么,你應該如何使用多個字段進行左連接?
我認為你需要使用into
關鍵字並在連接之后解決丟失的子節點的DefaultIfEmpty(),而不是之前:
...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>()
on new { auth.PayerID, tpd.ServiceTypeID, bool RequiresPrescription = true }
equals new { pstr.PayerID, pstr.ServiceTypeID, pstr.RequiresPrescription }
into pstrs
from PSTR in pstrs.DefaultIfEmpty()
select new {
Payer = auth.Payer,
Prescription = rx,
TreatmentPlanDetail = tpd,
Rules = PSTR
};
LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
可能會LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
null,因為返回的DataTable不包含任何行 ,從而導致異常。 請注意, in
之后的整個語句將在選擇之前執行,這不是您期望的行為。 您希望匹配的行,如果不存在匹配的行,則返回null。
對於布爾問題,它是一個命名問題(沒有匹配右側的“RxReq”,左側沒有匹配“RequiresPrescription”)。 嘗試命名true
“RequiresPrescription”,如上所述(或命名右側的pstr.RequiresPrescription
“RxReq”)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.