2016-08-25 10 views
0

私は3つのテーブルを持っています。
linq join query nullを返す

id name des   table2  table3 
1 xyz TableA_des1 null  1 
2 abc TableA_des2 1   2 
3 hgd TableA_des2 2   3 

表B

id name des   Active 
1 xyz TableB_des1 1 
2 abc TableB_des2 1 
3 hgd TableB_des2 1 

表C

id name des   Active 
1 xyz TableC_des1 1 
2 abc TableC_des2 1 
3 hgd TableC_des2 1 

LINQのクエリ

var res = (from a in TableA 
       where id = 1 

       join b in TableB on a.table2 equals b.id into ab 
       from bdata in ab.DefaultIfEmpty() 
       where bdata.Active = true 

       join c in TableC on a.table3 equals c.id into ac 
       from cdata in ac.DefaultIfEmpty() 
       where cdata.Active = true 

       select new { data1 = a.name, data2 = bdata?? string.Empty, data3 = cdata?? string.Empty}) 

約クエリがnullを与えています。デバッグ時の変数resにはnullがあります。

+1

'null'なのでが、空のコレクションを返さない: - 実際に第三の方法は、(最初​​の2つのオプションが好ましいalthought)が存在することを意味

は、明示的なnullチェックを含みます。 Linqクエリは 'null'を返しません。(ヌルかもしれない特定のレコードを取得しない限り) –

答えて

3

whereの条件は、に効果的に変換されるため、範囲の変数がleft outer joinの右側から来ることを避けてください。

from a in TableA 
where id = 1 

join b in TableB.Where(x => a.Active) 
on a.table2 equals b.id 
into ab 
from bdata in ab.DefaultIfEmpty() 

join c in TableC.Where(x => x.Active) 
on a.table3 equals c.id 
into ac 
from cdata in ac.DefaultIfEmpty() 

... 

か(可能な場合)参加に含めるを:

from a in TableA 
where id = 1 

join b in TableB 
on new { id = a.table2, Active = true } equals new { b.id, b.Active } 
into ab 
from bdata in ab.DefaultIfEmpty() 

join c in TableC 
on new { id = a.table3, Active = true } equals new { c.id, c.Active } 
into ac 
from cdata in ac.DefaultIfEmpty() 

... 

理由を理解するためには

代わりに、あなたは参加前をフィルタリング右サイドを適用する必要がありますどちらかそれは、bdatanullである場合(つまり一致するレコードがない場合)where bdata.Active == trueを評価しようとします。実際にこれがLINQ to Objectsの場合、上記の基準はNullReferenceExceptionを生成します。しかし、LINQ to Entitiesは、データベースが当然NULLでないカラムのクエリでnullの値を自然にサポートするため、例外なしで処理できます。したがって、上記のシンプルさはfalseと評価され、その結果のレコードをフィルタリングし、一致する右側のレコードが存在するかどうかにかかわらず、定義によって左側のレコードを返すことになるleft outer joinの効果を効果的に削除します。

from a in TableA 
where id = 1 

join b in TableB 
on a.table2 equals b.id 
into ab 
from bdata in ab.DefaultIfEmpty() 
where bdata == null || bdata.Active 

join c in TableC 
on a.table3 equals c.id 
into ac 
from cdata in ac.DefaultIfEmpty() 
where cdata == null || cdata.Active 

... 
+0

それはうまく答えを記述できます – anand

+0

それは明らかではありません - 右側に一致するレコードがない場合'bdata.Active = true'は' false'と評価され、クエリがレコードを返すのを妨げています。 –

+0

linqに10個の結合が残っていると、performane issueが発生する – anand