Assuming I have a left outer join as such:
from f in Foo
join b in Bar on f.Foo_Id equals b.Foo_Id into g
from result in g.DefaultIfEmpty()
select new { Foo
Turning Marc Gravell's answer into an extension method, I made the following.
internal static IEnumerable> LeftJoin(
this IEnumerable left,
IEnumerable right,
Func selectKeyLeft,
Func selectKeyRight,
TRight defaultRight = default(TRight),
IEqualityComparer cmp = null)
{
return left.GroupJoin(
right,
selectKeyLeft,
selectKeyRight,
(x, y) => new Tuple>(x, y),
cmp ?? EqualityComparer.Default)
.SelectMany(
x => x.Item2.DefaultIfEmpty(defaultRight),
(x, y) => new Tuple(x.Item1, y));
}