2009-07-07 15 views
12

why left joins in Linq can't use defined relationships ile ilgili daha önce bir soru sordum; Bugüne kadar tatmin edici bir cevabım yok.Birleştirmede birden fazla alan varsa Linq'e nasıl katılınır?

Şimdi, paralel bir yolda, join anahtar sözcüğünü, nesnelerim arasında hiçbir ilişki tanımlanmamış gibi kullanmam gerektiğini kabul ettim ve sorgumu Linq'de nasıl ifade edeceğimi anlamaya çalışıyorum. Sorun şu ki, birden fazla tablo arasında, birleştirme işleminde yer alan birden çok alan bulunan birleşik soldan birleşme. Bu basitleştirme hiçbir yolu işte tüm Maskelenmemiş ihtişamıyla SQL var, var:

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 

(Bilginize, ben yapmaya çalışıyorum anlamak yardımcı olur: Ben eğer varsa tanımlamaya çalışıyorum . yetki Payer bu ServiceType için reçete gerektirir, ancak hiçbir ServicePerscription kayıt ya, ya da süresi dolmuş bu Patient için TreatmentPlanDetail kayıtları) Şimdi

, burada benim C# kodu göründüğünü gibi:

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 }; 

Oops, derleme yapmıyor! Bir sebepten dolayı (bir açıklama isterdim) Equijoin içinde bu gerçek booleanı kullanamıyorum! ama çalıştırdığınızda, ben "set nesne başvurusu değil" bir olsun - İyi, ben bunu bırakın ve daha sonra "RequiresPrescription" şeyler filtre ...

... 
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty() 
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID } 
... 

... ve şimdi derler edeceğiz bu satırdaki istisna. DUH! Elbette orada bir boş var! Sol taraftaki biriyle bir karşılaştırmayı başka nasıl yapmanız gerekir, eğer sağ taraftaki nesneyi referans gösteremezseniz, bu potansiyel olarak boş olabilir?

Peki, birden çok alanı kullanarak nasıl bir sol birleştirme yapmalısınız?

+1

Boole sorunu için, adlandırma sorununu bulamadınız mı (sağ tarafta "RxReq" ile hiçbir şey eşleşmiyor ve hiçbir şey "Sol taraftaki RequesisPrescription" ile eşleşmiyor)? Boole "RequetPrescription" yazarak veya özellikle sağ tarafın pstr.RequiresPrescription "RxReq" ismini vermeyi deneyin. –

cevap

14

Olmadığını önce, katılmak sonra eksik çocuk DefaultIfEmpty() into anahtar kelime kullanmak ve çözmek gerekir düşünüyorum: DataTable döndü içerdiğinden

... 
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() muhtemelen bir null yukarı çeviriyor hiçbir satır, böylece istisna neden olur. in'dan sonra ifadenin tamamını seçmeden önce gerçekleştirin, bu sizin istediğiniz davranış değildir. Eşleşen satırlar veya eşleşen satır yoksa, null olmasını istersiniz. boolean sorun için


, bu (hiçbir şey sağ tarafta "RxReq" ile eşleşir ve hiçbir şey sol tarafta "RequiresPrescription" eşleşir) bir adlandırma sorundur. Yukarıdaki gibi (veya sağ tarafın pstr.RequiresPrescription "RxReq" adını taşıyan) true "RequesPrescription" yazarak deneyin.

+3

... ya da sadece pes et, aklını koru ve Dapper.net gibi bir mikro ORM kullan – niico

İlgili konular