EF4.2 additional left outer joint with one table

I know there are some questions about this already, most refer to either old issues that have been resolved or a few tables. This issue is not addressed in any of the other problems "left outer join" that I have seen, I receive INNER JOIN

and LEFT OUTER JOIN

for the same table with the same request.

Table outline:

Users: id (PK)
       Name (VARCHAR) 
       ProfileImageUri (VARCHAR)
Locations: id (PK)
LocationBPNTips: id (PK)
                 TipText (VARCHAR)
                 CreatedAt (Datetime)
                 UserId (int) (FK to User.id, navigation property is called User)
                 LocationId (int) (FK to Location.id)

      

(there is more, but this is not relevant :))

In my scenario, I am querying a referenced table through a projection and I get an extra left outer join, this is what I am running (the commented parts are not relevant to the problem, commented out for cleaner SQL, EF does (even better than I imagine represented :)):

LocationBPNTips
     .Where(t => t.LocationId == 33)
     //.OrderByDescending(t => intList.Contains(t.UserId))
     //.ThenByDescending(t => t.CreatedAt)
     .Select(tip => new LocationTipOutput
     {
             CreatedAt = tip.CreatedAt,
             Text = tip.TipText,
             LocationId = tip.LocationId,
             OwnerName = tip.User.Name,
             OwnerPhoto = tip.User.ProfileImageUri
     }).ToList();

      

And this is the generated SQL

SELECT 
[Extent1].[LocationId] AS [LocationId], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[TipText] AS [TipText], 
[Extent2].[Name] AS [Name], 
[Extent3].[ProfileImageUri] AS [ProfileImageUri]
FROM   [dbo].[LocationBPNTips] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Users] AS [Extent3] ON [Extent1].[UserId] = [Extent3].[Id]
WHERE 33 = [Extent1].[LocationId]

      

As you can see is LEFT OUTER JOIN

executed on the same tableINNER JOIN

I think the optimal code would be (note: I renamed Extent3 to Extent2 manually and added a comment, this was not generated by EF !!) - with my current data it runs about 22% faster (with sorting, this% should be higher no sorting) since no additional connection is needed.

SELECT 
[Extent1].[LocationId] AS [LocationId], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[TipText] AS [TipText], 
[Extent2].[Name] AS [Name], 
[Extent2].[ProfileImageUri] AS [ProfileImageUri]
FROM   [dbo].[LocationBPNTips] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserId] = [Extent2].[Id]
--LEFT OUTER JOIN [dbo].[Users] AS [Extent3] ON [Extent1].[UserId] = [Extent3].[Id]
WHERE 33 = [Extent1].[LocationId]

      

Various queries I have tried (projection of anonymous type in them):

LocationBPNTips
     .Where(t => t.LocationId == 33)
     //.OrderByDescending(t => intList.Contains(t.UserId))
     //.ThenByDescending(t => t.CreatedAt)
     .Select(tip => new 
     {
             CreatedAt = tip.CreatedAt,
             Text = tip.TipText,
             LocationId = tip.LocationId,
             OwnerName = tip.User,
             OwnerPhoto = tip.User
     }).ToList()

      

The SQL output was flawed, it double-sampled the users table in the same format as above, internal and then external. I think I understand why this is happening in this case, because I was querying for the data twice, although this could have been done in memory and not SQL with an extra join - but in my case I did not ask twice, I asked for different columns just one time. I did this test to make sure the double join is consistent.

I also tried to run:

LocationBPNTips
    .Where(t => t.LocationId == 33)
    .Select(tip => new 
    {
            CreatedAt = tip.CreatedAt,
            Text = tip.TipText,
            LocationId = tip.LocationId,
            OwnerName = tip.User.Name
    }).ToList()

      

This returns a clean, single inner join as expected, but that's not what I am trying to do

So the question is : Is this a bug? Am I using EF wrong?

+2


source to share


1 answer


I've seen a similar issue before. We can call this a bug or a feature. EF Query Building is far from ideal. The ADO.NET team fixes some issues with each major release. I don't have the June 2011 CTP installed to check if this also happens when I first view the next version.

Edit:



As per this answer, a similar issue was fixed in the June CTP 2011.

0


source







All Articles