結合に複数のフィールドがある場合、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 }
...

...これでコンパイルは完了しましたが、実行すると、この行で「オブジェクト参照が設定されていません」という例外が発生します。 当たり前だ! もちろんそこにはヌルがあります!右側のオブジェクトを参照することが許可されていない場合、潜在的に null になる可能性がある場合、左結合との比較を他にどのように実行すればよいでしょうか?

では、複数のフィールドを使用して左結合を行うにはどうすればよいでしょうか?

役に立ちましたか?

解決

を使用する必要があると思います 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() おそらく null が返されるのは、 返された DataTable には行が含まれていません, したがって、例外が発生します。後のステートメント全体に注目してください in は選択する前に実行されますが、これは望ましい動作ではありません。一致する行が必要です。一致する行が存在しない場合は null が必要です。


ブール値の問題の場合、これは名前付けの問題です (右側の「RxReq」に一致するものはなく、左側の「RequiresPrescription」に一致するものはありません)。名前を付けてみてください true 上記のように「RequiresPrescription」(または右側の名前を付けます) pstr.RequiresPrescription 「RxReq」)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top