开发手册 欢迎您!
软件开发者资料库

Entity Framework - 并发

Entity Framework并发 - 从概述,体系结构,环境设置,数据库设置,数据模型,DbContext,类型,关系,生命周期,代码优先方法,模型优先方法,数据库优先方法,DEV方法,数据库操作,并发,开始学习实体框架事务,视图,索引,存储过程,断开连接的实体,表值函数,本机SQL,枚举支持,异步查询,持久性,投影查询,命令记录,命令拦截,空间数据类型,继承,迁移,渴望,懒惰,显式加载,验证,跟踪更改,彩色实体,第一个示例,数据注释,Fluent API,种子数据库,代码优先迁移,多个DbContext,嵌套实体类型。

任何数据访问开发人员在回答有关数据并发的问题时都会遇到困难,"如果同时有多个人同时编辑相同的数据,会发生什么?"

  • 我们中更幸运的是处理业务规则,说"没问题,最后一个赢."

  • 在这种情况下,并发不是问题.更可能的是,它不是那么简单,并且没有灵丹妙药可以同时解决每个场景.

  • 默认情况下,实体框架将采用"最后一个胜利"的路径,意味着即使其他人在检索时间数据和保存时间数据之间更新了数据,也会应用最新更新.

让我们举个例子来更好地理解它.以下示例在课程表中添加新列VersionNo.

课程表

转到设计器并右键单击设计器窗口并从数据库中选择更新模型...

Designer

您会看到课程实体中添加了另一列.

课程实体

右键单击新创建的列VersionNo并选择Properties并将ConcurrencyMode更改为Fixed,如下图所示.

New Created Column

将Course.VersionNo的ConcurrencyMode设置为Fixed,无论何时更新课程,Update命令都会显示使用EntityKey及其VersionNo属性的课程.

让我们看一个简单的场景.两个用户同时检索相同的课程,用户1将该课程的标题更改为数学并在用户2之前保存更改.稍后当用户2更改在用户1保存其更改之前检索到的该课程的标题时, case user 2将获得并发异常"User2:Optimistic Concurrency exception occurred".

using System;using System.Data.Entity;using System.Data.Entity.Infrastructure;using System.Linq;namespace DatabaseFirstDemo {   class Program {      static void Main(string[] args) {         Course c1 = null;         Course c2 = null;         //User 1 gets Course         using (var context = new UniContextEntities()) {            context.Configuration.ProxyCreationEnabled = false;            c1 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();         }         //User 2 also get the same Course         using (var context = new UniContextEntities()) {            context.Configuration.ProxyCreationEnabled = false;            c2 = context.Courses.Where(s ⇒ s.CourseID == 1).Single();         }         //User 1 updates Course Title         c1.Title = "Edited from user1";         //User 2 updates Course Title         c2.Title = "Edited from user2";         //User 1 saves changes first         using (var context = new UniContextEntities()) {            try {               context.Entry(c1).State = EntityState.Modified;               context.SaveChanges();            } catch (DbUpdateConcurrencyException ex) {               Console.WriteLine("User1: Optimistic Concurrency exception occurred");            }         }         //User 2 saves changes after User 1.         //User 2 will get concurrency exection         //because CreateOrModifiedDate is different in the database         using (var context = new UniContextEntities()) {            try {               context.Entry(c2).State = EntityState.Modified;               context.SaveChanges();            } catch (DbUpdateConcurrencyException ex) {               Console.WriteLine("User2: Optimistic Concurrency exception occurred");            }         }      }   }}