DefaultIfEmpty()如何暗示外连接?

时间:2016-02-24 15:49:51

标签: c# sql linq-to-sql linqpad

这是怎么回事:

from c in Contacts
join a in Addresses
on c.Address_ID equals a.Address_ID
into Temp
from d in Temp.DefaultIfEmpty()
where c.First_Name.ToUpper().Contains("Pin".ToUpper())
select new { id = c.Contact_ID, value = (c.First_Name??"") + " " + (c.Last_Name??"") + " " + (c.Company_Name??""), FirstName = c.First_Name, LastName = c.Last_Name, AddressFull = d.Address_Full, Phone = c.Phone, Email = c.Email, CompanyName = c.Company_Name }

转换为此(使用LinqPad)?

SELECT [t0].[Contact_ID] AS [id], ((((COALESCE([t0].[First_Name],@p1)) + @p2) + (COALESCE([t0].[Last_Name],@p3))) + @p4) + (COALESCE([t0].[Company_Name],@p5)) AS [value], [t0].[First_Name] AS [FirstName], [t0].[Last_Name] AS [LastName], [t1].[Address_Full] AS [AddressFull], [t0].[Phone], [t0].[Email], [t0].[Company_Name] AS [CompanyName]
FROM [Contact] AS [t0]
LEFT OUTER JOIN [Address] AS [t1] ON [t0].[Address_ID] = ([t1].[Address_ID])
WHERE UPPER([t0].[First_Name]) LIKE @p0

似乎Temp.DefaultIfEmpty() == LEFT OUTER JOIN

这种语法背后的原因是什么?有人可以雄辩地解释一下原因吗?

1 个答案:

答案 0 :(得分:2)

这不是一个神奇的咒语。您可以使用纯LINQ to Objects获得相同的语义。 join into已经是左连接。它将所有匹配项放入集合中。可以是零个项目或多个项目。

from d in Temp.DefaultIfEmpty()将是一个内部联接,因为如果没有匹配项,我们将删除外部行。 DefaultIfEmpty现在可用于添加“虚拟空值”以使其成为左连接。

这整个模式有点尴尬,但背后有逻辑。