如何在Entity Framework 6 Database First中实现导航属性的乐观并发

问题描述

如果您的实体具有导航属性(即父表和子表之间的许多关系),那么在实体框架数据库中实现乐观并发的惯用方法是什么?您是否需要检查父实体和子实体的行版本,或者是否只检查父实体的行版本就足以知道是否有任何子表以及任何父表都已更新?

考虑 2 个表:

Table Parent {
   ParentId INT PRIMARY KEY,ValueParent INT
   Version ROWVERSION
}


Table Child {
   ParentId INT FOREIGN KEY
   ChildId INT,ValueChild INT
   Version ROWVERSION
  (ParentId,ChildId) Primary Key
}

转换为实体后,表格将如下所示:

class Parent{
   int ParentId;
   int valueParent;
   byte[] version;
   virtual ICollection<Child> Children
}

class Child{
   int parentId;
   int childId;
   int valueChild;
   byte[] version;
}

如果我加载一个 Parent 对象,并且只更新其上的子实体,

parent.Children.ElementAt(0).valueChild = 1 //

在db中,子实体中的rowversion会递增,但父rowversion将保持不变。那有效吗?如果我想实现乐观并发,我仍然需要对父级和子级进行行版本检查,以确保模型没有改变。我可以将两个实体的版本的 concurrency mode 设置为 fixed,但这不会阻止在我进行更新之前必须在开始时进行检查,对吗?

如果您的实体之间有一对多关系,那么实现乐观并发的惯用方法是什么?有什么方法可以做到这一点,我只需要检查父行版本,还是需要始终检查任何子元素的行版本?

解决方法

对每一行进行乐观并发检查,您只需将该列配置为 Timestamp/Rowversion,EF 将为您生成并发检查。

有什么方法可以做到我只需要检查父行版本

正如@Jeremy Lakeman 所建议的那样,如果您始终在任何子项更改时更新父项,则可以检测并防止来自您的 EF 应用程序的并发违规。但它无法防止对子行进行临时更新。