Why does Entity Framework 6 generate complex SQL queries for simple lookups?

前端 未结 4 1366
半阙折子戏
半阙折子戏 2020-12-17 01:07

I have this LINQ query

dbContext.Customers.Where(c => c.AssetTag == assetTag).Count();

or

(from c in dbContext.Customers         


        
相关标签:
4条回答
  • 2020-12-17 01:23

    That WHERE condition is generated this way because with ANSI NULLS setting, comparing AssetTag == null will not return the corresponding rows in SQL (since in SQL world when comparing null to null the result is null). To keep the query behavior the same as a C# developer would expect, EF generates the extended WHERE clause. Note that previous versions of EF did not do so and thus did not work on databases with ANSI NULLS setting.

    The GroupBy projection is there because EF supports much more complex queries before the .Count() call, such as joins, projections etc. This approach is thus more generic as it will work work all those scenarios as well.

    0 讨论(0)
  • 2020-12-17 01:33

    In EF6 the database null semantics is the default comparison semantics. Note that this is a change to the default setting in EF5. In EF5 this flag was buried in ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior and by default EF would use Linq to Object comparison semantics. In EF6 it is exposed on DbContext as DbContext.Configuration.UseDatabaseNullSemantics. You can find more details here

    0 讨论(0)
  • 2020-12-17 01:34

    in C# string equivalency, null == null evaluates to True. null == null in the database evaluates to False. The script is verifying that either both the column value and the parameter are null, or that both are not null and they have the same string value.

    WHERE 
        (
            -- neither the column nor the paramter are null and
            -- the column and the parameter have the same string value
            ([Extent1].[AssetTag] = @p__linq__0) AND 
            ( NOT ([Extent1].[AssetTag] IS NULL    OR @p__linq__0 IS NULL))
        ) 
        OR 
        (
            -- both the column value and the parameter are null
            ([Extent1].[AssetTag] IS NULL) AND 
            (@p__linq__0 IS NULL)
        )
    
    0 讨论(0)
  • For one thing, in C# c.AssetTag == assetTag would be true if both are null. In SQL however, null compared to anything is always false. Therefore, if we want to generate a query that follows C# comparison mechanics, we must add additional conditions to ensure null compares evaluate to true if both are null:

    ([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)

    0 讨论(0)
提交回复
热议问题