Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架-底层SQL语句_C#_Sql_Linq_Entity Framework - Fatal编程技术网

C# 实体框架-底层SQL语句

C# 实体框架-底层SQL语句,c#,sql,linq,entity-framework,C#,Sql,Linq,Entity Framework,下面是我在实体框架中执行的一个简单的linq查询 db.Responses.FirstOrDefault(r => r.QuestionId.Equals(“1.1.1”) && r.User.Id.Equals(user.Id) && !r.IsDeleted); 这里的QuestionId是一个varchar数据类型列,db是上下文对象 我启动了EntityProfiler来查看引擎盖下发生了什么,而底层SQL查询似乎有一大堆似乎有点多余的

下面是我在实体框架中执行的一个简单的
linq
查询

    db.Responses.FirstOrDefault(r => r.QuestionId.Equals(“1.1.1”) && r.User.Id.Equals(user.Id)   && !r.IsDeleted);
这里的
QuestionId
是一个
varchar
数据类型列,db是上下文对象

我启动了EntityProfiler来查看引擎盖下发生了什么,而底层SQL查询似乎有一大堆似乎有点多余的语句

/* 1 */    SELECT TOP (1) *
/* 2 */    FROM   [dbo].[Responses] AS [Extent1]
/* 3 */    WHERE  ((([Extent1].[QuestionId] = '1.1.1' /* @p__linq__0 */)
/* 4 */     AND (NOT ([Extent1].[QuestionId] IS NULL
/* 5 */                OR '1.1.1' /* @p__linq__0 */ IS NULL)))
/* 6 */     OR (([Extent1].[QuestionId] IS NULL)
/* 7 */         AND ('1.1.1' /* @p__linq__0 */ IS NULL)))
/* 8 */    AND ([Extent1].[UserId] = 1 /* @p__linq__1 */)
/* 9 */    AND (1 /* @p__linq__1 */ IS NOT NULL)
/* 10 */   AND ([Extent1].[IsDeleted] <> cast(1 as bit))
所以,问题是为什么实体框架会加入所有这些额外的代码? 为什么第4行和第6行是必要的,where条款中唯一相关的语句是第3、5和7行


我正在尝试优化我的SQL语句,任何关于EntityFramework为什么要这样做的想法都会很有帮助。我在Visual studio 2013中使用EF6。

这是因为字符串“1.1.1”作为sql命令参数传递,而sql生成器对参数值一无所知。Ef不会根据值生成不同的语句。即使传递的值为null,语句也必须正确

当列可为null时,如果列和参数值都为null,则Equals必须为true。当它不可为null时,只有当传递的值不为null时,它才能为true

EF所做的每一件事都是100%有效的,并且执行得非常正确。除非得到错误的结果,否则不要尝试进行优化。

行:

/* 3 */    WHERE  ((([Extent1].[QuestionId] = '1.1.1' /* @p__linq__0 */)
/* 4 */     AND (NOT ([Extent1].[QuestionId] IS NULL
/* 5 */                OR '1.1.1' /* @p__linq__0 */ IS NULL)))

应该解释C#/VB.NET和SQL之间空比较的语义差异。您可以使用
DbContext.Configuration.UseDatabaseNullSemantics
ObjectContextOptions.UseCSharpNullComparisonBehavior
控制行为。您可以找到更多详细信息和。

比较值如何:
r.QuestionId==“1.1.1”
?@WiktorZychla r.QuestionId==“1.1.1”没有区别,也不应该有区别。Equals和“==”都是等价的,r.QuestionId==“1.1.1”代码保持不变。我认为这并不意味着性能有很大的提高,但是有没有办法避免EF生成这些幼稚的语句?@e.campver性能是无用的如果逻辑错误,EF生成带有显式空值检查的语句的性能会更好,因为查询分析器会忽略空值的额外条件检查。
/* 3 */    WHERE  ((([Extent1].[QuestionId] = '1.1.1' /* @p__linq__0 */)
/* 4 */     AND (NOT ([Extent1].[QuestionId] IS NULL
/* 5 */                OR '1.1.1' /* @p__linq__0 */ IS NULL)))