modest violet

modest violet

開発者としてのあれこれや、日々の雑記など

your future hasn't written yet. no one's has.
by Emmett Lathrop "Doc" Brown

LINQ to SQLで複合キーのExists句を書く

単一のExists句を表す場合はContainsを使用していましたが、複数のキーでExistsを実現させねばならない状況に陥ったので、勉強がてらにまとめました。

単一キーのExistsの場合

基となるSQL
SELECT * FROM table_A as A
 WHERE EXISTS (
    SELECT * FROM table_B As B
     WHERE A.Key1 = B.Key1 
    )
メソッド式(C#
table_A
    .Select(s => s)
    .Where(t1 => table_B.Select(t2 = > t2.Key1) 
                        .Contains(t1.Key1)

ポイントは、table_Bで一致させたい項目をSelectで絞り込んだ結果に対して、Containsを行う点です。
IN句に近いイメージですが、生成されるSQLはEXISTSになります。

複合キーのExistsの場合

基となるSQL
SELECT * FROM table_A as A
 WHERE EXISTS (
    SELECT * FROM table_B As B
     WHERE A.Key1 = B.Key1
       AND A.Key2 = B.Key2
       AND B.Key3 = @Key3
    )
メソッド式(C#
table_A
   .Select (s => s)
   .Where(t1 => table_B.Where(p => @Key3 == p.Key3)
                       .Any(t2 => t2.Key1 == t1.Key1 
                               && t2.Key2 == t1.Key2))

table_BをKey3で絞り込んだ結果をさらにAny判定でtable_Aと比較します。
この際、table_BはWhere句で条件を指定します。Anyだとコンパイルエラーになります。何故ならば、table_Bの結果を持ってtable_Aと比較するので、Anyだと結果が返らない為です。

うーん、奥が深い。