Как выйти из объединения в 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

(К вашему сведению, если это поможет понять, что я пытаюсь сделать:Я пытаюсь определить, есть ли они 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 };

Упс, не компилируется!По какой-то причине (мне бы хотелось объяснений) я не могу использовать это буквальное логическое значение внутри эквивалентного соединения!Хорошо, я оставлю это и отфильтрую «RequiresPrescription» позже...

...
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 будет выполнен перед выбором в нем, что не является вашим желаемым поведением.Вам нужны совпадающие строки или ноль, если соответствующих строк не существует.


Что касается логической проблемы, это проблема именования (ничто не соответствует «RxReq» справа и ничего не соответствует «RequiresPrescription» слева).Попробуйте назвать true «RequiresPrescription», как указано выше (или назовите правую сторону). pstr.RequiresPrescription «RxReq»).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top