Linq针对实体框架4.1代码首先生成LEFT OUTER JOIN

时间:2011-07-26 20:26:30

标签: linq-to-entities entity-framework-4.1

我不知道这是否是形成这个linq查询的最佳方式,但我刚刚开始,所以任何建议都表示赞赏。

以下查询我认为“报告中包含任何项目,其中项目具有任何属性,其中大小属性的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获取位置名称,当它刚刚从第一个INNER 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 个答案:

答案 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的情况,它只是假设您知道如果报告没有位置,您的代码将会中断。