EF4发布了奇怪的SQL语句

时间:2011-10-06 12:06:33

标签: sql-server entity-framework-4

我正在分析Entity Framework v4.0应用程序,并注意到以下SQL:

exec sp_executesql N'declare @p int
  update [dbo].[Table]
  set @p = 0
  where ((([Id] = @0) and ([Property1] = @1)) and ([Property2] = @2))
  ',N'@0 uniqueidentifier,@1 int,@2 int',@0='[some-guid]',@1=0,@2='0'

我真的很想知道这段代码到底是做什么的。我的意思是,我不理解其中的SQLish意义。它并不真正更新表,它只是将@p参数设置为0,如果该表至少有一行与where子句匹配。但@p并没有在其他地方使用。为什么EF会这样做?

感谢您的任何见解!

修改

该声明在

中的其他声明中发布
Context.SaveChanges();

呼叫。孤立它的努力将是相当可观的。

也许重要的是要提到事情发生在事务中,其隔离级别设置为'SERIALIZABLE'。

2 个答案:

答案 0 :(得分:3)

这看起来毫无意义。

假设查询有任何理由可以发送,我唯一可以想到的是它正在寻找“x行受影响”的消息。

然而,发布一个update语句来获取这个而不仅仅是直接SELECT COUNT()在锁定和日志记录方面是次优的。

答案 1 :(得分:2)

出于我的想法,我有几个可能的推测:

  • 它正在尝试计算受更新语句影响的记录数,并在此基础上应用许多不同策略中的一种。您可以证明或反驳这一猜想,增加或减少受影响记录的数量,并查看此后的陈述是否有任何变化。
  • 在可序列化的隔离级别中,您仍然可以获得读取和写入锁定,但这可能是在其他方案中避免幻像读取的方法。 this document末尾的表说,在SS 2008中,在可序列化的隔离级别中,幻像读取应该是不可能的,但也许EF人员使用相同的代码用于可能发生幻像读取的其他隔离级别(RU,RC和RR)。

后者更难以反驳,并且两者都可能最终成为一个错误,如果它导致您的方案中出现问题,您可能必须联系EF开发团队的某个人(大数据集的性能下降,我想象)。