- 实体框架教程
- 实体框架 - 首页
- 实体框架 - 概述
- 实体框架 - 架构
- 实体框架 - 环境设置
- 实体框架 - 数据库设置
- 实体框架 - 数据模型
- 实体框架 - DbContext
- 实体框架 - 数据类型
- 实体框架 - 关系
- 实体框架 - 生命周期
- 实体框架 - 代码优先方法
- 实体框架 - 模型优先方法
- 实体框架 - 数据库优先方法
- 实体框架 - 开发方法
- 实体框架 - 数据库操作
- 实体框架 - 并发
- 实体框架 - 事务
- 实体框架 - 视图
- 实体框架 - 索引
- 实体框架 - 存储过程
- 实体框架 - 脱机实体
- 实体框架 - 表值函数
- 实体框架 - 原生SQL
- 实体框架 - 枚举支持
- 实体框架 - 异步查询
- 实体框架 - 持久化
- 实体框架 - 投影查询
- 实体框架 - 命令日志
- 实体框架 - 命令拦截
- 实体框架 - 空间数据类型
- 实体框架 - 继承
- 实体框架 - 迁移
- 实体框架 - 积极加载
- 实体框架 - 延迟加载
- 实体框架 - 显式加载
- 实体框架 - 验证
- 实体框架 - 跟踪更改
- 实体框架 - 彩色实体 (此处翻译可能需要根据实际含义调整)
- 实体框架 - 代码优先方法
- 实体框架 - 第一个示例
- 实体框架 - 数据注解
- 实体框架 - Fluent API
- 实体框架 - 种子数据库
- 实体框架 - 代码优先迁移
- 实体框架 - 多个DbContext
- 实体框架 - 嵌套实体类型
- 实体框架资源
- 实体框架 - 快速指南
- 实体框架 - 有用资源
- 实体框架 - 讨论
实体框架 - 并发
任何数据访问开发人员在回答关于数据并发的问题时都会遇到困难,“如果多个人同时编辑相同的数据会发生什么?”
我们当中比较幸运的人会处理这样的业务规则:“没问题,最后保存的获胜”。
在这种情况下,并发不是问题。更可能的是,情况并非如此简单,并且没有万能的解决方案可以一次解决所有场景。
默认情况下,实体框架将采用“最后保存的获胜”的方式,这意味着即使有人在检索数据和保存数据之间更新了数据,也会应用最新的更新。
让我们来看一个例子来更好地理解它。下面的例子在Course表中添加了一个新的列VersionNo。
转到设计器,右键单击设计器窗口,然后选择“从数据库更新模型…”。
您将看到在Course实体中添加了另一列。
右键单击新创建的列VersionNo,选择“属性”,并将并发模式更改为“固定”,如下面的图像所示。
将Course.VersionNo的ConcurrencyMode设置为Fixed后,每当更新Course时,Update命令将使用其EntityKey和VersionNo属性查找Course。
让我们来看一个简单的场景。两个用户同时检索相同的课程,用户1将该课程的标题更改为数学并保存更改,然后是用户2。稍后,当用户2更改在用户1保存更改之前检索到的该课程的标题时,用户2将收到并发异常“**用户2:发生了乐观并发异常**”。
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"); } } } } }
广告