一、首先添加并发处理标记

在需要进行并发处理的类中添加版本号,并在版本号上使用[Timestamp]标记:

public class Department
{
public int Id { get; set;}
public ……
public int? InstructorId{ get; set; }
public ICollection<Course> Courses {get; set; }

//版本号
[Timestamp]
public byte[] RowVersion{get; set; }
}

二、然后更新数据库

add-migration updateTimestampForDeparment

update-database

三、重新建基架项目

删除Create和Edit页面内关于RowVersion项目的输入项

四、打开编辑Edit的控制器,修改如下:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int? id, byte[]rowVersion)
{
if(id==null)
{
return NoFound();
}
//先查一下数据是否存在
var department= await
_context.Departments.Include(a=>a.Administrator)
.SingleOrDefaultAsync(a=>a.Id==id); if(department==null)
{
var deletedDepartment = new Department();
await TryUpdateModeAsync(deletedDepartment);
ModelState.AddModelError(string.Empty,"无法进行数据的修改,该部门信息已经被其他人删除!);
ViewBag.InstructorId = new SelectList(_context.Instructors, "Id","RealName",deletedDepartment);
return View(deletedDepartment);
} //将RowVersion标志原来的值变更为新的值
_context.Entry(department).Property("RowVersion").OriginalValue = rowVersion; if(await TryUpdateModelAsync<Department>(department, a=>a.Name, a=>a.StartDate, a=>a.Budge(a=>a.InstructorId))
{
try
{
await _context.SaveChangesAsync();
return RedireToAction(nameof(Index));
              }
catch(DbUpdateException ex)
{
var exceptionEntity = ex.Entries.Single();
var clienValue = (Department)exceptionEntity.Entity; var databaseEntity = exceptionEntity.GetDatabaseValues();
if(databaseEntity == null)
{
ModelState.AddModelError(string.Empty, "无法进行数据的修改,该部门信息已经被其他人删除!);
}
else{
var databaseValues=(Dapartment)databaseEntity.ToObject();
if(databaseValues.Budget != clienValue.Budget)
{
ModelState.AddModelErrow("Budget", $"当前值:{databaseValues.Budget}");
}
                      if(databaseValues.StartDate != clienValue.StartDate)
{
ModelState.AddModelErrow("StartDate", $"当前值:{databaseValues.StartDate}");
}
                      if(databaseValues.InstructorId != clienValue.InstructorId)
{
var instructorEntity = await _context.Instructors.SingleOrDfaultAsync(a=>a.Id == databaseValues.InstructorId);
ModelState.AddModelErrow("InstructorId", $"当前值:{instructorEntity?.RealName}");
}
ModelState.AddModelErrow("", "你正在编辑的记录已经被其他用户所修改,编辑操作已经被取消,数据库当前的值已经显示在页面,请再次点击保存。否则请返回列表"); department.RowVersion=(byte[])databaseValues.RowVersion;
ModelState.Remove("RowVersion");
                   }
}
}
        ViewBag.InstructorId=new SelectList(_context.Instructors, "Id","RealName",deletedDepartment)

        return View(department);
}

五、修改Edit视图

添加版本号字段到Form中

<input type="hidden" asp-for="RowVersion" />

六、修改删除控制器

public async Task<IActionResult> Delete(int? id, bool? concurrencyError)
{
if( id == null)
{
return NotFound();
} var department = await _context.Departments
.include(d=>d.Administrator).AsNoTracking()
.singleOrDefaultAsync(m=>m.Id==id);
if(department == null)
{
if(concurrencyError.GetValueOrDefault());
{
return RedirectToAction(nameof(Index));
}
return NotFound();
} if(concurrencyError.GetValueOrDefault());
{
ViewBag.concurrencyErrow = "你正在删除的信息,已经被别人修改了,当前操作会被取消,如果你要继续删除该条信息,请重新点击删除按钮,否则请返回列表";
} return View(department);
}

七、修改删除确认控制器

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(Department department)
{
try
{
if(await _context.Departments.AnyAsync(a=>a.Id==department.id)
{
_context.Departments.Remove(department);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
catch(DbUpdateException e)
{
return RedirectToAction(nameof(Delete),new {concurrencyError = true, id = department.Id});
}
}

八、修改删除视图

在视图中添加报错信息的显示块:

<p class="text-denger">@Viewbag.</p>

使用EFCore处理并发冲突的更多相关文章

  1. Linq to Sql : 并发冲突及处理策略

    原文:Linq to Sql : 并发冲突及处理策略 1. 通过覆盖数据库值解决并发冲突 try { db.SubmitChanges(ConflictMode.ContinueOnConflict) ...

  2. LINQ-to-SQL那点事~LINQ-to-SQL中的并发冲突与应对

    回到目录 在上一篇文章中提到了并发冲突,还说详细的说明在这讲来说,呵呵,那现在就说一下吧! 并发冲突产生的原因 事实上,linq to sql中的并发冲突是指记录在进行update操作时,客户端A1取 ...

  3. Mego开发文档 - 处理并发冲突

    处理并发冲突 数据库并发是指多个进程或用户同时访问或更改数据库中的相同数据的情况.并发控制是指用于确保存在并发更改时数据一致性的特定机制. Mego实现了乐观并发控制,这意味着它可以让多个进程或用户独 ...

  4. asp.net core 系列之并发冲突

    本文介绍如何处理多个用户并发更新同一实体(同时)时出现的冲突 . 主要是两种:一种,检查属性并发冲突,使用 [ConcurrencyCheck] ;另一种,检测行的并发冲突,使用 rowversion ...

  5. MySQL事物(一)事务隔离级别和事物并发冲突

    数据库的操作通常为写和读,就是所说的CRUD:增加(Create).读取(Read).更新(Update)和删除(Delete).事务就是一件完整要做的事情.事务是恢复和并发控制的基本单位.事务必须始 ...

  6. Linq to Sql并发冲突及处理策略

    0. 并发冲突的示例 单用户的系统现在应该比较罕见了,一般系统都会有很多用户在同时进行操作:在多用户系统中,涉及到的一个普遍问题:当多个用户“同时”更新(修改或者删除)同一条记录时,该如何更新呢?   ...

  7. C# 开放式并发冲突报错处理

    1.调用DataSet.GetChanges()获取数据源中改变的数据 var data = ViewData.GetChanges() as ReleaseData; 2.为新增的数据 data 加 ...

  8. Elasticsearch由浅入深(四)ES并发冲突、悲观锁与乐观锁、_version乐观锁并发

    ES并发冲突 举个例子,比如是电商场景下,假设说,我们有个程序,工作的流程是这样子的: 读取商品信息(包含了商品库存) 用户下单购买 更新商品信息(主要是将库存减1) 我们比如咱们的程序就是多线程的, ...

  9. 分布式缓存重建并发冲突和zookeeper分布式锁解决方案

    如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...

随机推荐

  1. 虹软离线人脸识别 ArcFace 2.0 Demo [C++]

    环境: win10(10.0.16299.0)+ VS2017 sdk版本:ArcFace v2.0 OPENCV3.43版本 x64平台Debug.Release配置都已通过编译 下载地址:http ...

  2. MySQL 存储过程 if语句

    MySQL  存储过程 if语句 MySQL IF语句允许您根据表达式的某个条件或值结果来执行一组SQL语句. 要在MySQL中形成一个表达式,可以结合文字,变量,运算符,甚至函数来组合.表达式可以返 ...

  3. reactiveCocoa使用注意点

    @RACSubject信号 注意点:1如果一个页面需要多次发送这个消息,那么似乎会暴露一个bug,信号不会被销毁,等到发送第二个信号 时,第一个信号仍然会被发送,导致错误,比如一个tableView的 ...

  4. LeetCode--030--串联所有单词的字串(java)

    给定一个字符串 s 和一些长度相同的单词 words.找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置. 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要 ...

  5. Python函数分类及操作

    为什么使用函数? 答:函数的返回值可以确切知道整个函数执行的结果   函数的定义:1.数学意义的函数:两个变量:自变量x和因变量y,二者的关系                      2.Pytho ...

  6. Intel收购半导体设计公司eASIC

    来源:本文由公众号 半导体行业观察(ID:icbank)翻译自「anandtech」,谢谢. 北京时间今天凌晨,Intel宣布收购了半导体设计公司eASIC. eASIC的商业模式介于传统Fables ...

  7. mongodb+express+nodejs(登陆退出)

    1.安装expressnpm i -g express(新版本4.X以上要安装express-generator)npm i -g express-generator 2.安装mongodb下载地址h ...

  8. OLLVM特性、使用原理

    一.OLLVM特性 目前ollvm支持的特性有以下几种: 指令替换 -mllvm -sub 虚假控制流 -mllvm -bcf 打平控制流 -mllvm -fla 函数(Funtions)注解 二.指 ...

  9. 关于footer 小于一屏还要在底部显示的思考

    首先想到了页面是动态的  就是js 计算 但是有一个简单的方法就是 运用定位 1 footer 的祖先元素没有定位属性 absoulite (这样他就会相对于文档定位) left:0 bottom : ...

  10. windows/linux VPS云服务器限制IP访问,限制别人的IP访问网站方法

    服务器VPS云服务器如何限制IP访问,限制别人的IP访问网站的方法 windows主机IIS限制IP访问方法:首先打开IIS点击“网站”,右键属性,(如果仅给单个网站设置,请选择下边的站点,点右键“属 ...