كيف تركت الانضمام إلى LinQ إذا كان هناك أكثر من حقل في الصلة؟
-
11-09-2019 - |
سؤال
سألت سؤالا في وقت سابق لماذا اليسار ينضم في 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
(FYI، إذا كان ذلك يساعد على فهم ما أحاول القيام به: أحاول تحديد ما إذا كان هناك أي TreatmentPlanDetail
سجلات لهذا Patient
حيث التفويض 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! حسنا، سأترك الأمر، وتصفية الأشياء "المتداخل" في وقت لاحق ...
...
join pstr in LinqUtils.GetTable<PayerServiceTypeRules>().DefaultIfEmpty()
on new { auth.PayerID, tpd.ServiceTypeID } equals new { pstr.PayerID, pstr.ServiceTypeID }
...
... والآن يجمع - ولكن عندما أركض، أحصل على استثناء استثناء "مرجع كائن" على هذا السطر. ده! بالطبع هناك فارغة هناك! كيف من المفترض أن تقوم بإجراء مقارنة مع انضمام يساري، إذا لم يسمح لك بالإشارة إلى الكائن على الجانب الأيمن، فقد يكون ذلك فارغا؟
لذلك، كيف من المفترض أن تفعل الانضمام الأيسر باستخدام حقول متعددة؟
المحلول
أعتقد أنك بحاجة إلى استخدام 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()
ربما يحول فارغة بسبب تم إرجاع Datatable لا يحتوي على صفوف, ، مما تسبب استثناء الخاص بك. لاحظ البيان بأكمله بعد in
سيتم تنفيذها قبل تحديدها، والتي ليست سلوكك المطلوب. تريد صفوف مطابقة أو NULL إذا لم تكن هناك صفوف مطابقة موجودة.
بالنسبة للمشكلة المنطقية، إنها مشكلة في التسمية (لا يوجد شيء يطابق "RXREQ" على الجانب الأيمن ولا شيء يطابق "متتدلال" على الجانب الأيسر). حاول تسمية true
"متتدلال" كما لدي أعلاه (أو اسم الجانب الأيمن pstr.RequiresPrescription
"RXREQ").