为什么Entity Framework 6为简单查找生成复杂的SQL查询?
我有这个LINQ查询
dbContext.Customers.Where(c => c.AssetTag == assetTag).Count();
要么
(from c in dbContext.Customers where c.AssetTag == assetTag select c).Count();
生成的SQL是
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT COUNT(1) AS [A1] FROM [dbo].[Customer] AS [Extent1] WHERE (([Extent1].[AssetTag] = @p__linq__0) AND ( NOT ([Extent1].[AssetTag] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)) ) AS [GroupBy1]
那么为什么LINQ会为一个简单的where语句生成如此复杂的SQL呢?
在EF6中,数据库空语义是默认的比较语义。 请注意,这是对EF5中默认设置的更改。 在EF5中,此标志隐藏在ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior中 ,默认情况下EF将使用Linq to Object比较语义。 在EF6中,它在DbContext上公开为DbContext.Configuration.UseDatabaseNullSemantics 。 你可以在这里找到更多细节
在C#string equivalency中, null == null
计算结果为True
。 数据库中的null == null
计算结果为False
。 该脚本将validation列值和参数是否为空,或者两者都不为空且它们具有相同的字符串值。
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) )
WHERE条件是以这种方式生成的,因为使用ANSI AssetTag == null
设置,比较AssetTag == null
将不会返回SQL中的相应行(因为在SQL世界中,将null与null进行比较时结果为null)。 为了使查询行为与C#开发人员期望的相同,EF生成扩展的WHERE子句。 请注意,以前版本的EF没有这样做,因此不适用于具有ANSI NULLS设置的数据库。
GroupBy投影就在那里,因为EF在.Count()调用之前支持更复杂的查询,例如连接,投影等。因此,这种方法更通用,因为它也适用于所有这些场景。
首先,在C# c.AssetTag == assetTag
,如果两者都为null, c.AssetTag == assetTag
true。 但是在SQL中,与任何事物相比,null始终为false。 因此, 如果我们想要生成一个遵循C#比较机制的查询 ,我们必须添加其他条件以确保null如果两者都为null,则将evaluate与true进行比较:
([Extent1].[AssetTag] IS NULL) AND (@p__linq__0 IS NULL)
上述就是C#学习教程:为什么Entity Framework 6为简单查找生成复杂的SQL查询?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/996882.html