Entity Framework 支持 SQL rowversion

标签 sql entity-framework rowversion

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

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

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

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

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

最佳答案

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

  • RowVersion(或 TimeStamp 字段类型)在 SQL 中的字段与任何其他字段一样(除了是强制性的和自增的)。在更新时有一个特定的数据库处理它的值(即增加它),但没有特定的数据库处理在更新之前比较它的值。
  • 另一侧的
  • EF 允许您为每个字段( ConcurrencyMode )定义 edmx 。如果需要,您可以将所有字段标记为 ConcurrencyMode=Fix(而不是默认的 None ),从而将所有字段都包含在更新的 where 子句中(将实体的原始值与数据库中记录的当前值进行比较)。但使用该模式为每个实体设置一个字段更容易,即 RowVersion 字段。特别是因为唯一为您维护它的一方是数据库。
  • 完成此操作后,您一定会收到 System.Data.OptimisticConcurrencyException 隔离错误。您仍然必须远离操作对象集的 EF 工作流,例如使用 myObjectSet.Attach(myEntity) ,它会访问数据库以获取当前数据并将您的更改合并到其中。由于RowVersion字段正常情况下是不变的,更新会以数据库的当前值触发,不会导致并发异常。
  • 关于 Entity Framework 支持 SQL rowversion,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22193961/

    相关文章:

    c# - 使用 LINQ Entity Framework 的 LEFT JOIN 或 RIGHT JOIN

    tsql - T-SQL "timestamp"覆盖 "rowversion"数据类型列

    sql - Oracle/sql/jpa - 对于一年跨度表,如何选择每 7 天具有最大数据(一列)的行?

    mysql - 如何将多个 SELECT 输出输入到 MySQL 的 FROM 子句中?

    c# - 包含相同对象列表的对象的 Entity Framework 映射

    sql-server - 如何在不更改行版本的情况下更新记录

    sql-server - ServiceStack Ormlite 和 RowVersion 支持

    mysql - 使用 mySQL 查找今天的免费房间

    sql - 在 SQL 中,如何形成 XML 输出,其中属性值之一为 XML,无需 <,> 编码

    c# - WebSecurity.InitializeDatabaseConnection 不配合代码优先迁移