Bu yöntem (uzantı) sözdizimini kullanarak sol dış birleşimler için de facto SO soru gibi göründüğü için, (en azından benim deneyimimde) daha yaygın olarak ne olduğunu şu anda seçili cevaba bir alternatif ekleyeceğini düşündüm sonra
// Option 1: Expecting either 0 or 1 matches from the "Right"
// table (Bars in this case):
var qry = Foos.GroupJoin(
Bars,
foo => foo.Foo_Id,
bar => bar.Foo_Id,
(f,bs) => new { Foo = f, Bar = bs.SingleOrDefault() });
// Option 2: Expecting either 0 or more matches from the "Right" table
// (courtesy of currently selected answer):
var qry = Foos.GroupJoin(
Bars,
foo => foo.Foo_Id,
bar => bar.Foo_Id,
(f,bs) => new { Foo = f, Bars = bs })
.SelectMany(
fooBars => fooBars.Bars.DefaultIfEmpty(),
(x,y) => new { Foo = x.Foo, Bar = y });
Basit bir veri kümesi kullanarak farkı görüntülemek için (değerlerin kendilerine katıldığımızı varsayarak):
List<int> tableA = new List<int> { 1, 2, 3 };
List<int?> tableB = new List<int?> { 3, 4, 5 };
// Result using both Option 1 and 2. Option 1 would be a better choice
// if we didn't expect multiple matches in tableB.
{ A = 1, B = null }
{ A = 2, B = null }
{ A = 3, B = 3 }
List<int> tableA = new List<int> { 1, 2, 3 };
List<int?> tableB = new List<int?> { 3, 3, 4 };
// Result using Option 1 would be that an exception gets thrown on
// SingleOrDefault(), but if we use FirstOrDefault() instead to illustrate:
{ A = 1, B = null }
{ A = 2, B = null }
{ A = 3, B = 3 } // Misleading, we had multiple matches.
// Which 3 should get selected (not arbitrarily the first)?.
// Result using Option 2:
{ A = 1, B = null }
{ A = 2, B = null }
{ A = 3, B = 3 }
{ A = 3, B = 3 }
Seçenek 2, tipik sol dış birleşim tanımı için doğrudur, ancak daha önce de belirttiğim gibi, veri setine bağlı olarak genellikle gereksiz karmaşıktır.
GroupJoin
sol dış birleşim yapar,SelectMany
parça sadece seçmek istediğiniz şeye bağlı olarak gereklidir.