zoukankan      html  css  js  c++  java
  • 使用EFCore处理并发冲突

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

    在需要进行并发处理的类中添加版本号,并在版本号上使用[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>
  • 相关阅读:
    CodeForces Gym 100500A A. Poetry Challenge DFS
    CDOJ 486 Good Morning 傻逼题
    CDOJ 483 Data Structure Problem DFS
    CDOJ 482 Charitable Exchange bfs
    CDOJ 481 Apparent Magnitude 水题
    Codeforces Gym 100637G G. #TheDress 暴力
    Gym 100637F F. The Pool for Lucky Ones 暴力
    Codeforces Gym 100637B B. Lunch 找规律
    Codeforces Gym 100637A A. Nano alarm-clocks 前缀和
    TC SRM 663 div2 B AABB 逆推
  • 原文地址:https://www.cnblogs.com/sky-net/p/9242775.html
Copyright © 2011-2022 走看看