كيف تركت الانضمام إلى LinQ إذا كان هناك أكثر من حقل في الصلة؟

StackOverflow https://stackoverflow.com/questions/1093494

سؤال

سألت سؤالا في وقت سابق لماذا اليسار ينضم في 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").

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top