【发布时间】:2011-05-23 02:26:36
【问题描述】:
更新(2010-12-21):根据我一直在做的测试完全重写了这个问题。此外,这曾经是 POCO 特定的问题,但事实证明我的问题不一定是 POCO 特定的。
我正在使用实体框架,并且我的数据库表中有一个时间戳列,应该用于跟踪乐观并发的更改。我已在实体设计器中将此属性的并发模式设置为“固定”,但结果不一致。下面是几个简化的场景,它们展示了并发检查在一种场景中有效,但在另一种场景中无效。
成功抛出 OptimisticConcurrencyException:
如果我附加一个断开连接的实体,如果存在时间戳冲突,SaveChanges 将抛出 OptimisticConcurrencyException:
[HttpPost]
public ActionResult Index(Person person) {
_context.People.Attach(person);
var state = _context.ObjectStateManager.GetObjectStateEntry(person);
state.ChangeState(System.Data.EntityState.Modified);
_context.SaveChanges();
return RedirectToAction("Index");
}
不抛出 OptimisticConcurrencyException:
另一方面,如果我从数据库中检索我的实体的新副本并在某些字段上进行部分更新,然后调用 SaveChanges(),那么即使存在时间戳冲突,我也不会得到一个 OptimisticConcurrencyException:
[HttpPost]
public ActionResult Index(Person person) {
var currentPerson = _context.People.Where(x => x.Id == person.Id).First();
currentPerson.Name = person.Name;
// currentPerson.VerColm == [0,0,0,0,0,0,15,167]
// person.VerColm == [0,0,0,0,0,0,15,166]
currentPerson.VerColm = person.VerColm;
// in POCO, currentPerson.VerColm == [0,0,0,0,0,0,15,166]
// in non-POCO, currentPerson.VerColm doesn't change and is still [0,0,0,0,0,0,15,167]
_context.SaveChanges();
return RedirectToAction("Index");
}
基于 SQL Profiler,Entity Framework 似乎忽略了新的 VerColm(它是时间戳属性),而是使用最初加载的 VerColm。因此,它永远不会抛出 OptimisticConcurrencyException。
更新:根据 Jan 的要求添加额外信息:
请注意,我还在上述代码中添加了 cmets,以与我在执行此示例时在控制器操作中看到的内容一致。
这是更新前我的数据库中 VerColm 的值:0x0000000000000FA7
以下是执行更新时 SQL Profiler 显示的内容:
exec sp_executesql N'update [dbo].[People]
set [Name] = @0
where (([Id] = @1) and ([VerColm] = @2))
select [VerColm]
from [dbo].[People]
where @@ROWCOUNT > 0 and [Id] = @1',N'@0 nvarchar(50),@1 int,@2 binary(8)',@0=N'hello',@1=1,@2=0x0000000000000FA7
请注意,@2 应该是 0x0000000000000FA6,但它是 0x0000000000000FA7
这是更新后我的数据库中的 VerColm:0x0000000000000FA8
有谁知道我可以如何解决这个问题?当我更新现有实体并且存在时间戳冲突时,我希望 Entity Framework 引发异常。
谢谢
【问题讨论】:
-
请发布保存的代码。
-
我无法重现这个。当我尝试保存具有时间戳冲突的加载和修改的实体时,我得到一个 OptimisticConcurrencyException。你确定你有时间戳冲突吗?您能否发布您的分析 SQL 查询?
-
嗨 Jan,我根据您的要求在上面添加了其他信息。
标签: c# asp.net entity-framework concurrency poco