不幸的是,LINQ中既沒有外連接,也不能添加任意連接條件。內部連接可以使用DefaultIfEmpty解決,但是連接條件的Bn.type = n部分需要移動到where條件。
下產生正是你所提供的SQL,除了我所提到的類型的條款:
from A in products
join B1 in categories on A.key equals B1.key into tmp_color
join B2 in categories on A.key equals B2.key into tmp_size
join B3 in categories on A.key equals B3.key into tmp_shape
from B1 in tmp_color.DefaultIfEmpty()
from B2 in tmp_size.DefaultIfEmpty()
from B3 in tmp_shape.DefaultIfEmpty()
where B1.type == 1 && B2.type == 2 && B3.type == 3
select new { product = A, color = B1.category, size = B2.category, shape = B3.category };
結果
exec sp_executesql N'SELECT [t0].[key], [t1].[category] AS [color], [t2].[category] AS [size], [t3].[category] AS [shape]
FROM [Product] AS [t0]
LEFT OUTER JOIN [Category] AS [t1] ON [t0].[key] = [t1].[key]
LEFT OUTER JOIN [Category] AS [t2] ON [t0].[key] = [t2].[key]
LEFT OUTER JOIN [Category] AS [t3] ON [t0].[key] = [t3].[key]
WHERE ([t1].[type] = @p0) AND ([t2].[type] = @p1) AND ([t3].[type] = @p2)',N'@p0 int,@p1 int,@p2 int',@p0=1,@p1=2,@p2=3
(更新:這是LINQ到SQL,只是假設EF會是類似的。)
Albin的答案更具可讀性,但可能會產生不太理想的SQL。爲了與SQL完全匹配,您需要用DefaultIfEmpty替換FirstOrDefault,儘管(根據您的數據可能沒有區別)。 (對不起,目前還不能評論;-))
小問題 - LINQ本身沒有明確的外連接,但在實體框架中使用LINQ,有很多查詢格式導致外連接 - 例如var people = db.Person.Include(p => p.Address)當Id地址附加時可以爲空 - EF將它解釋爲您的左外連接。 – 2013-11-22 21:30:01