Как выполнить левое внешнее соединение с использованием методов расширения linq

Поскольку это, по-видимому, де-факто linq-to-sql вопрос SO для левых внешних c# соединений с использованием c# синтаксиса метода (расширения), я csharp подумал, что добавлю альтернативу csharp текущему выбранному ответу, который linq-to-sql (по крайней мере, по моему sql-to-linq опыту) чаще был тем, что lambda Я после

// 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 });

Чтобы отобразить разницу, используя visual-c# простой набор данных (при c#-language условии, что мы объединяем linq-to-sql сами значения):

List tableA = new List { 1, 2, 3 };
List tableB = new List { 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 tableA = new List { 1, 2, 3 };
List tableB = new List { 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    }    

Вариант 2 c# соответствует типичному определению lambda левого внешнего соединения, но, как visual-c# я упоминал ранее, часто бывает c#.net излишне сложным в зависимости c#.net от набора данных.

c#

linq-to-sql

lambda

2022-11-15T21:35:12+00:00