2011-07-26 30 views
2

我不知道这是形成这个linq查询的最佳方式,但我刚刚开始,所以任何建议表示赞赏。Linq对实体框架4.1代码首先产生左外部连接

以下查询我认为“报告中有任何项目的项目具有任何属性,其中大小属性的waiste大小属性为32.”返回报告的位置密钥,ID和名称。 (位置是从报表外键。)

 var rpts = from x in ctx.Reports 
        where x.ReportItems.Any(y => 
         y.ItemAttributes.Any(z => 
          z.Sizing.WaistSize == 32)) 
        select new { x.Key, x.Location.ID, x.Location.Name }; 

这将产生预期的效果,但SQL看起来不正确我。注意LEFT OUTER JOIN来获取地点名称,当它可能只是从第一内得到它加入到同一个表...

SELECT [Extent1].[ReportKey] AS [ReportKey], 
     [Extent2].[LocationID] AS [LocationID], 
     [Extent3].[LocationName] AS [LocationName] 
FROM [Info].[Report] AS [Extent1] 
INNER JOIN [Info].[Location] AS [Extent2] 
ON [Extent1].[LocationKey] = [Extent2].[LocationKey] 
LEFT OUTER JOIN [Info].[Location] AS [Extent3] 
ON [Extent1].[LocationKey] = [Extent3].[LocationKey] 
WHERE EXISTS 
(SELECT 1 AS [C1] 
FROM (SELECT [Extent4].[ReportItemKey] AS [ReportItemKey] 
     FROM [Info].[ReportItems] AS [Extent4] 
     WHERE [Extent1].[ReportKey] = [Extent4].[ReportKey] 
    ) AS [Project1] 
WHERE EXISTS (SELECT 1 AS [C1] 
     FROM [Info].[ItemAttributes] AS [Extent5] 
     INNER JOIN [Info].[Attributes] AS [Extent6] 
        ON [Extent5].[AttributeKey] = [Extent6].[AttributeKey] 
     WHERE ([Project1].[ReportItemKey] = [Extent5].[ReportItemKey]) 
        AND ([Extent6].[WaistSize] = @p__linq__0) 
      ) 
) 

感谢您的时间。

回答

1

如果你想要一个内部联接,你将不得不写这样的事情

from x in ctx.Reports 
join y in ctx.Locations 
on x.LocationKey equals y.ID 
where x.ReportItems.Any(y => 
     y.ItemAttributes.Any(z => 
      z.Sizing.WaistSize == 32)) 
    select new { x.Key, y.ID, y.Name }; 

什么你写在select语句说x.Location.ID是导航到该实体的位置,不检查,看看不管你是否已经处理x.Locationnull的情况,它只是假设你知道如果报告没有位置,代码将会中断。