sql与linq lambda表达式的左连接

时间:2011-07-14 14:22:38

标签: .net linq

我在使用linq进行左/右连接时遇到问题。

我已经说过了

public class Customer
{
  prop string CustomerId { get; set; }
  prop string LanguageGuid { get; set; }
}

public class ReadOnlyCustomer
{
  prop string CustomerId { get; set; }
  prop string LanguageGuid { get; set; }
}

我在ReadonlyCustomer表中有很多客户。 在我的情况下,我没有客户表中的所有客户。 所以我不能使用Join,我不喜欢内部联接。 我需要左或右连接。

var test = db.Customer.Join(db.ReadOnlyCustomer, p => p.CustomerId, o => o.CustomerId, (c, o) => new ReadOnlyCustomer() { CustomerId = c.CustomerId, LanguageGuid = o.LanguageGuid ?? c.LanguageGuid });

此时,我得到一个空指针,因为查询无法连接空引用。

如何执行左连接等于sql left join,其中我获取数据源中不存在的值的NULL。

这需要在lampda中理解语法,如(来自o ......)

// dennis

1 个答案:

答案 0 :(得分:4)

您需要使用GroupJoin,有时结合对DefaultIfEmpty()的调用,以便为该组提供单个空值。然后,您可以使用SelectMany()每对最终得到一个结果,并注意结果中的一个值可能为空。

例如:

// Note: can only do a *left* join, so "bigger" table comes first
var test = db.ReadOnlyCustomer
             .GroupJoin(db.Customer,
                        p => p.CustomerId,
                        o => o.CustomerId,
                        (p, os) => new { p, os = os.DefaultIfEmpty() })
             // Each pair may have multiple os here
            .SelectMany(pair => pair.os.Select(o => new { pair.p, o }))
            // Flattened, but o may be null
            .Select(pair => new ReadOnlyCustomer {
                      CustomerId = pair.p.CustomerId,
                      LanguageGuid = o != null ? o.LanguageGuid ?? p.LanguageGuid
                                               : p.LanguageGuid
                    });

(出于兴趣,为什么这需要使用lambda语法而不是查询表达式?通常,所有类型的连接在查询表达式中都更容易表达。)