5

我的项目针对 SQL Server 2012 使用 EF(使用自跟踪模板测试版本 4,使用默认模板测试版本 5,所有数据库优先)。数据库表定义了每个rowversion( timestamp) 列。

在它的核心中使用 EF,这意味着我的数据库更新代码看起来是这样的:

using (var db = new MyContext())
{
  //db.Entry(myInstance).State = EntityState.Modified;
  db.SaveChanges();
}

不会触发任何rowversion警报。我运行并行客户端,每个客户端读取相同的记录,对其进行更改,然后每个将其写入数据库。接受所有更新,不应用并发。

我是否必须为我的更新命令使用存储过程(使用 where 子句说明我的rowversion值)才能让 EF 确认“内置”并发性,或者是否有另一种方式(配置、特定方法调用)来使我的代码工作?

4

2 回答 2

9

这是答案(我已经给了 POC 几个星期的时间):

  1. RowVersion(或TimeStamp字段类型)inSQL是与其他任何字段一样的字段(强制和自增除外)。更新时有一个特定的数据库处理它的值(即递增它),但没有特定的数据库处理比较它在更新之前的值。
  2. EF另一方面,您可以ConcurrencyMode为每个字段定义 ( edmx)。如果需要,您可以使用ConcurrencyMode=Fix(而不是 default None)标记所有字段,从而将所有字段包含在更新的 where 子句中(将实体的原始值与数据库中记录的当前值进行比较)。但是RowVersion使用该模式更容易为每个实体设置一个字段,即字段。特别是因为唯一为您维护它的一方是数据库。
  3. 一旦你这样做了,你肯定会得到System.Data.OptimisticConcurrencyException隔离错误。您仍然必须远离EF操纵您的对象集的工作流,例如使用myObjectSet.Attach(myEntity),它会访问数据库以获取当前数据并将您的更改合并到其中。由于该RowVersion字段通常是不变的,因此更新将使用数据库中的当前值触发,并且不会导致并发异常。
于 2014-03-19T08:04:23.807 回答
1

如果是这样,您是否希望处理并发,请查看此链接:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/handling-concurrency-with-the-entity-framework-in-an-asp-net- mvc-应用程序

于 2014-03-05T16:56:19.397 回答