How to implement left join in JOIN Extension method

早过忘川 提交于 2019-11-27 03:50:29
Jon Skeet

Normally left joins in LINQ are modelled with group joins, sometimes in conjunction with DefaultIfEmpty and SelectMany:

var leftJoin = p.Person.Where(n => n.FirstName.Contains("a"))
                       .GroupJoin(p.PersonInfo, 
                                  n => n.PersonId,
                                  m => m.PersonId,
                                  (n, ms) => new { n, ms = ms.DefaultIfEmpty() })
                       .SelectMany(z => z.ms.Select(m => new { n = z.n, m }));

That will give a sequence of pairs (n, m) where n is the entry from p.Person and m is the entry from p.PersonInfo, but m will be null if there are no matches.

(It's completely untested, btw - but should give you the idea anyway :)

Harun Khan

For Left outer Join try Following query. This is tested

var leftJoin = Table1
                .GroupJoin(
                               inner: Table2,
                    outerKeySelector: t1 => t1.Col1,
                    innerKeySelector: t2 => t2.Col2,
                      resultSelector: ( t1, t2Rows ) => new { t1, t2Rows.DefaultIfEmpty() }
                )
                .SelectMany( z =>
                    z.t2Rows.Select( t2 =>
                        new { t1 = z.t1, t2 = t2 }
                    )
                );

If anyone comes across this question and wants an extension method to accomplish this, I created one using the same approach as the other answers. It has the same signature as the regular join extension method.

    public static IEnumerable<TResult> LeftJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,
        IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector,
        Func<TOuter, TInner, TResult> resultSelector)
    {
        return outer
            .GroupJoin(inner, outerKeySelector, innerKeySelector, (outerObj, inners) =>
            new 
            {
                outerObj,
                inners= inners.DefaultIfEmpty()
            })
        .SelectMany(a => a.inners.Select(innerObj => resultSelector(a.outerObj, innerObj))); 
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!