【发布时间】:2011-06-03 20:16:17
【问题描述】:
在浏览 SQL 分析器时,我注意到 EF4 生成了以下查询。
exec sp_executesql N'declare @p int
update [dbo].[User]
set @p = 0
where (([UserID] = @0) and ([RowVersion] = @1))
select [RowVersion]
from [dbo].[User]
where @@ROWCOUNT > 0 and [UserID] = @0',N'@0 int,@1 binary(8)',@0=1,@1=0x000000000042DDCD
我不确定为什么 EF4 会生成这个,而我实际上并没有更新 UnitOfWork 中 User 表的任何列。运行此查询会更新 RowVersion 列(时间戳数据类型),这会导致下一个 UnitOfWork 中出现 OptimisticConcurrencyException。
通过谷歌搜索,我找到了这个link,这证实了其他人也遇到了这种情况,但还没有找到解决方案。
非常感谢任何指针。
编辑:复制问题的示例代码。
User 和 Session 表具有外键关系。此外,在 EF4 中,我已将两个实体的 RowVersion 列的 "Concurrency Mode" 属性设置为 Fixed。
以下是复制场景的示例方法。
private static void UpdateSession()
{
using (var context = new TestEntities())
{
context.ContextOptions.ProxyCreationEnabled = false;
var session = context.Users.Include("Sessions").First().Sessions.First();
session.LastActivityTime = DateTime.Now;
context.ApplyCurrentValues("Sessions", session);
context.SaveChanges();
}
}
我从 Sql profiler 中看到以下由 EF4 生成的查询。
exec sp_executesql N'update [dbo].[Session]
set [LastActivityTime] = @0
where (([SessionID] = @1) and ([RowVersion] = @2))
select [RowVersion]
from [dbo].[Session]
where @@ROWCOUNT > 0 and [SessionID] = @1',N'@0 datetime2(7),@1 int,@2 binary(8)',@0='2011-06-20 09:43:30.6919628',@1=1,@2=0x00000000000007D7
接下来的查询很奇怪。
exec sp_executesql N'declare @p int
update [dbo].[User]
set @p = 0
where (([UserID] = @0) and ([RowVersion] = @1))
select [RowVersion]
from [dbo].[User]
where @@ROWCOUNT > 0 and [UserID] = @0',N'@0 int,@1 binary(8)',@0=1,@1=0x00000000000007D3
【问题讨论】:
-
在您调用
SaveChanges之前,您的User实体的状态是什么?您是否还更改了指向User的任何关系? -
@Ladislav Mrnka - 我检查了 ObjectStateManager 并且在 SaveChanges 之前用户实体的状态是未更改的。是的,我修改了一些与用户实体相关的实体,并且在调用 SaveChanges 时,除了所需/预期的 sql 之外,还会生成上述 sql。
-
那么关系呢?您是否更改了与该特定用户的任何关系?
-
@Ladislav Mrnka - 恐怕我没有正确回答您的问题。你的意思是如果我改变了用户实体的导航属性的任何属性?如果是这样,是的,我正在这样做。
-
以防万一如果您不修改导航属性,这个奇怪的更新是否仍然存在?
标签: entity-framework entity-framework-4