2010-09-25 68 views

回答

37

通常左聯接在LINQ採取與組建模連接,有時與DefaultIfEmptySelectMany結合:

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

這將使對一個序列(n,m)其中n是來自p.Person的條目和m是來自p.PersonInfo的條目,但是m如果沒有匹配,則爲空。

(這是完全未經測試,順便說一句 - 但應該給你的想法呢:)

+1

第一個匿名投影不起作用 - 編譯器說'無效的匿名類型成員聲明器。匿名類型成員必須聲明一個成員分配,簡單名稱或成員訪問' – chester89 2013-06-26 14:55:54

+1

@ chester89:修正,謝謝。 – 2013-06-26 14:58:15

11

對於LEFT OUTER JOIN試試下面的查詢。這是測試

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

如果有人遇到這個問題,並希望擴展方法來做到這一點,我用同樣的方法爲其他答案創建一個。它與常規聯接擴展方法具有相同的簽名。

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