やりたいこと
仕事でC#を使う機会があり、LINQの少し沼にはまったのでメモとして残しておきます。
C#とLINQを使うのは初めですので間違いがございましたらご指摘をお願い申し上げます。
以下のような左部外部結合のSQLをLINQでも書きたい。
SQL
SELECT
M2010.STOCKCD
, M2010.STOCKNM
, D5020.STOCKQTY
, MS080.UNITNM
FROM
M2010
LEFT OUTER JOIN D5020
ON M2010.STOCKCD = D5020.STOCKCD
AND D5020.HMNO = 'aa'
AND d5020.LOTNO = 'bb'
LEFT JOIN M0010
ON D5020.HMNO = M0010.HMNO
LEFT JOIN MS080
ON M0010.UNIT = MS080.UNIT
WHERE M2010.STOCKCD = 'cc'
手順
1.左部外部結合
https://qiita.com/H-Takayama/items/0e0a962f9ebc59547e4d
こちらの記事で左部外部結合のやり方が説明されています。
2.on句に複数条件の書き方
on new
{
メインテーブルカラム
*今回は変数もここに入れています
} equals new
{
結合するテーブルのカラム
}
この構文の後に外部結合のinto〜from句を記述する
二つの構文を組み合わせたLINQ
var result = (from m2010 in db.M2010
join d5020 in db.D5020 on
new
{
m2010.STOCKCD,
hmno,(上記SQLの’aa’)
lotno(上記SQLの’bb’)
}
equals new
{
d5020.STOCKCD,
d5020.HMNO,
d5020.LOTNO
} into d5020null
from subd5020 in d5020null.DefaultIfEmpty()
join m0010 in db.M0010 on subd5020.HMNO equals m0010.HMNO into m0010null
from subm0010 in m0010null.DefaultIfEmpty()
join ms080 in db.MS080 on subm0010.UNIT equals ms080.UNIT into ms080null
from subms080 in ms080null.DefaultIfEmpty()
where m2010.STOCKCD == ex_storage(上記SQLの’cc’)
select new
{
m2010.STOCKCD,
m2010.STOCKNM,
subd5020.STOCKQTY,
subms080.UNITNM
});
エラー:「join句のいずれかの式の型が正しくありません。'GroupJoin'の呼び出しで型を推論できませんでした。」
上記のLINQを実行してみたところエラーが発生。
エラーの原因
on句の複数条件の箇所で比較条件の名前が違うので比較できずにエラーが発生。
なので条件を変数に入れて比較対象の名前を同じにして再び実行。
(http://piyopiyocs.blog115.fc2.com/blog-entry-72.html を参照)
エラー修正後 LINQ
var result = (from m2010 in db.M2010
join d5020 in db.D5020 on
new
{
a = m2010.STOCKCD,
b = hmno,
c = lotno
}
equals new
{
a = d5020.STOCKCD,
b = d5020.HMNO,
c = d5020.LOTNO
} into d5020null
from subd5020 in d5020null.DefaultIfEmpty()
join m0010 in db.M0010 on subd5020.HMNO equals m0010.HMNO into m0010null
from subm0010 in m0010null.DefaultIfEmpty()
join ms080 in db.MS080 on subm0010.UNIT equals ms080.UNIT into ms080null
from subms080 in ms080null.DefaultIfEmpty()
where m2010.STOCKCD == ex_storage
select new
{
m2010.STOCKCD,
m2010.STOCKNM,
subd5020.STOCKQTY,
subms080.UNITNM
});