1、首先添加併發處理標記數據庫
在須要進行併發處理的類中添加版本號,並在版本號上使用[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; } }
2、而後更新數據庫async
add-migration updateTimestampForDeparmentspa
update-databasecode
3、從新建基架項目orm
刪除Create和Edit頁面內關於RowVersion項目的輸入項blog
4、打開編輯Edit的控制器,修改以下:get
[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);
}
5、修改Edit視圖input
添加版本號字段到Form中string
<input type="hidden" asp-for="RowVersion" />
6、修改刪除控制器
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); }
7、修改刪除確認控制器
[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}); } }
8、修改刪除視圖
在視圖中添加報錯信息的顯示塊:
<p class="text-denger">@Viewbag.</p>