簡體   English   中英

如果加入中有多個字段,你如何離開加入Linq?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM