30594


凄く基本的な事なのですが、

[code]

    var test = (from a in dataTable1
                join b in datatable2 on new {a.ID, a.date, a.No} equals {b.ID, b.date, b.No}
                select new {
                          a.ID,
                          a.date,
                          a.No,
                          b.coment,
                          b.sozai,
                          a.note
                          }).Distinct();
    
[/code]

joinした時の結果なのですが、  
これはa.ID, a.date, a.Noが共通のデータしか結果として出てこないのでしょうか？  
もし、dataTable1とdatatable2
の共通のデータプラスお互いのテーブルにしかないデータも同時に抽出したい場合はどのようなlinqとなるのでしょうか？  
また、 a.note,b.coment,b.sozaiに値が入っていなければ空白もしくはnullとして結果を表示したいです。  
ご教授いただけると幸いです。

.net 3.5  
windows 8.1


CC BY-SA 3.0
2016-11-22T06:35:52.280
30593
2016-11-22T10:54:07.000
2016-11-22T07:28:16.373
5750
19310
question
c# linq
linq joinについて


> これはa.ID, a.date, a.Noが共通のデータしか結果として出てこないのでしょうか？

`join`演算子を使うと内部結合になりますので結合できなかったエンティティの組は出力されません。

Entity
Frameworkで完全外部結合を実現するには一度両テーブルを`UNION`してから左外部結合を二回行うか、グループ化により代替する必要があります。

下記のコードは前者の方法を使用しています。

[code]

    var keys = datatable1.Select(_ => new { _.ID, _.date, _.No })
                    .Union(datatable2.Select(_ => new { _.ID, _.date, _.No }))
                    .Distinct();
    var test = from k in keys
                join a in datatable1 on new { k.ID, k.date, k.No } equals new { a.ID, a.date, a.No } into a2
                from a in a2.DefaultIfEmpty()
                join b in datatable2 on new { k.ID, k.date, k.No } equals new { b.ID, b.date, b.No } into b2
                from b in b2.DefaultIfEmpty()
                select new {
                    k.ID,
                    k.date,
                    k.No,
                    b.coment,
                    b.sozai,
                    a.note
                };
    
    test.Distinct();
    
[/code]

なお、

> また、 a.note,b.coment,b.sozaiに値が入っていなければ空白もしくはnullとして結果を表示したいです。

については外部結合を行った場合の結合されなかったエンティティのプロパティは既定値になります。ですので`string`を`null`としたいのであれば上のように特に工夫は必要ありません。`int`その他の値型は`0`となるので、この動作が不都合である場合は

[code]

    select new {
        …
        SomeProperty = (int?)a.SomeProperty,
        OtherProperty = a != null ? a.OtherProperty : -1,
        LastProperty = a.StringNotNullProperty != null ? a.LastProperty : -1,
        …
    }
    
[/code]

のようにキャストや三項演算を追加してやれば回避できます。


CC BY-SA 3.0
2016-11-22T07:18:27.203
30594
2016-11-22T10:54:07.000
2016-11-22T10:54:07.000
5750
5750
30593
answer