Frage

Ich fragte eine Frage früher über warum schließt sich links in Linq nicht definierten Beziehungen verwenden ; Ich habe keine zufriedenstellende Antwort auf Verabredung.

Nun, auf einer parallelen Strecke habe ich akzeptiert, dass ich das join Schlüsselwort verwenden müssen, als ob es keine Beziehung zwischen meinen Objekten definiert waren, und ich versuche, herauszufinden, wie meine Abfrage in Linq zum Ausdruck bringen. Das Problem ist, es ist ein Konglomerat von links zwischen mehreren Tabellen verknüpft, mit mehreren Feldern beteiligt in der Verknüpfung. Es gibt keine Möglichkeit, dies zu vereinfachen, also hier ist die SQL in all seiner Herrlichkeit nicht maskiert:

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, wenn es hilft zu verstehen, was ich versuche zu tun: Ich versuche, wenn es zu identifizieren irgendwelche TreatmentPlanDetail Aufzeichnungen für diese Patient wo der bevollmächtigte Payer für dieses ServiceType ein Rezept erfordert, aber es gibt auch keine ServicePerscription Datensatz oder es ist abgelaufen.)

Nun, hier ist, was mein C # Code wie folgt aussieht:

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, nicht kompilieren! Aus irgendeinem Grund (ich würde eine Erklärung Liebe) Ich nicht, dass die wörtliche boolean innerhalb des Equijoin verwenden können! Gut, ich lasse es aus und auszufiltern die „RequiresPrescription“ stuff später ...

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

... und jetzt stellt es - aber wenn ich laufe, bekomme ich einen „Objektverweis nicht festgelegt“ Ausnahme auf dieser Linie. DUH! Natürlich gibt es eine Null in there! Wie sonst soll man einen Vergleich mit einem links ausführen kommen, wenn Sie nicht erlaubt sind, das Objekt auf der rechten Seite zu verweisen, das könnte möglicherweise null sein?

Also, wie soll man nach links trete mit mehreren Feldern?

War es hilfreich?

Lösung

Ich glaube, Sie brauchen das into Schlüsselwort verwenden und beheben, um die fehlenden Kinder DefaultIfEmpty () nach die Verbindung nicht vor:

...
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() dreht wahrscheinlich eine Null, weil die Datatable ergab keine Zeilen enthält , so dass Ihre Ausnahme verursacht. Beachten Sie die gesamte Anweisung nach in hinein ausgeführt wird vor der Auswahl, die nicht die gewünschte Verhalten. Sie möchten die passenden Zeilen oder null, wenn keine passenden Zeilen vorhanden sind.


Für das boolean Problem ist es ein Namensproblem (nichts übereinstimmt „RxReq“ auf der rechten Seite und nichts paßt „RequiresPrescription“ auf der linken Seite). Versuchen Sie die Benennung der true „RequiresPrescription“, wie ich oben (oder nennen die pstr.RequiresPrescription über die rechte Seite „RxReq“).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top