Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is MigrationHistory causing Linq results to differ when specifying only a subset of columns?

I'm running a query against Entity Framework as follows:

var results = MyViewEntity.Where(row => row.someId == myTargetId);

Here, MyViewEntityrepresents a View in the database. For the result, I expected two rows where the values in only one column should differ. The actual result has two rows, but with all columns containing the same values.

Now if I change my query as follows...

MyViewEntity.Where(row => row.someId == myTargetId)
            .Select(row => row.MyTargetColumnName);

... The result will contain two different values, as I initially expected. Adding additional columns as follows still returns two rows, with differences in the expected columns:

MyViewEntity.Where(row => row.SomeId == myTargetId)
            .Select(row => new {
                                row.MyTargetColumnName, 
                                row.SomeOtherCol, 
                                row.ThirdColumn
                               });

This will let me "fix" the problem, by simply specifying a a large number of columns in my query. I would however, prefer not to do that, and I'd like to understand what causes the difference between
Where(...) and Where(...).Select(...).


Extra info (SQL):

I tried to figure this out using LinqPad, which generates the following SQL for each of the LINQ expressions. The sql clearly differs, but the reason for this, and exactly what it means, is still not clear to me. Is some kind of caching happening in Entity Framework, which messes up my result? In relation to MigrationHistory perhaps?

Where().Select():

SELECT 
[Extent1].[MyTargetColumnName] AS [MyTargetColumnName], 
[Extent1].[SomeOtherCol] AS [SomeOtherCol], 
[Extent1].[ThirdColumn] AS [ThirdColumn]
FROM [dbo].[MyViewNameInDb] AS [Extent1]
WHERE 123 = [Extent1].[SomeId]

Only Where():
Note: Running the last part (the final select-statement) on it's own as pure SQL returns two differing rows, as expected. Running the whole thing as a LINQ expression however, returns two identical rows:

SELECT TABLE_SCHEMA SchemaName, 
        TABLE_NAME Name FROM INFORMATION_SCHEMA.TABLES 
        WHERE TABLE_TYPE = 'BASE TABLE'
GO

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[__MigrationHistory] AS [Extent1]
)  AS [GroupBy1]
GO

SELECT TOP (1) 
[Extent1].[Id] AS [Id], 
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
GO

SELECT 
[Extent1].[FirstCol] AS [FirstCol], 
[Extent1].[SecondCol] AS [SecondCol], 
--- More clumns here, omitted for clarity..  
[Extent1].[LastCol] AS [LastCol]
FROM [dbo].[MyViewNameInDb] AS [Extent1]
WHERE 123 = [Extent1].[SomeId]
like image 644
Kjartan Avatar asked Nov 12 '22 17:11

Kjartan


1 Answers

At the generated SQL scripts, It's looks like you're passing two different parameter (myTargetId) values which apparently should yields different results.

At the Where().Select() SQL script:

WHERE 123 = [Extent1].[SomeId]

And at the Where() SQL script:

WHERE 1234 = [Extent1].[SomeId]
like image 197
Yair Nevet Avatar answered Nov 14 '22 22:11

Yair Nevet