GoClimbColorado
GoClimbColorado

Reputation: 1060

Linq against Entity Framework 4.1 Code First producing LEFT OUTER JOIN

I don't know if this is the best way to form this linq query, but I'm just getting started so any advice is appreciated.

The following query I think says "Reports that have any items where the items have any attibutes where the sizing attribute's waiste size property is 32." return the Report's Location Key, ID and Name. (Location is a foreign key from Report.)

        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 };

This produces the desired results but the SQL doesn't seem right to me. Notice the LEFT OUTER JOIN to get the Location Name, when it could have just gotten it from the first INNER JOIN to the same table...

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)
             )
 )

Thanks for the time.

Upvotes: 2

Views: 1028

Answers (1)

Eva Lacy
Eva Lacy

Reputation: 1317

If you want an inner join you will have to write something like this

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 };

What you wrote by saying x.Location.ID in the select statement is to navigate to the entity Location, it doesn't check to see whether you have handled the situation where x.Location is null, it just assumes that you know that if a report doesn't have a location your code will break.

Upvotes: 1

Related Questions