Entity Framework 乐观并发处理

小说:微赢棋牌透视作者:卓北乙建更新时间:2019-02-17字数:51591

“没,希巴前面四个小精灵我没猜错的话应该都会赢的,但是后面就难说了,所以面对希巴前面四个小精灵刘皓就要制造更大的优势,为的就是在后面的战斗里面尽可能的用这些优势来弥补不足。”布玛说道。

大众麻将在线

王小民冷笑一声道:“韩峰,我发现你是个忘性很大的人,这点很不好,要不要再让你体验一下,被毒蜂蜇到的滋味?”
心里对丁宁是艳羡不已,他拍了拍丁宁的肩膀,给了丁宁一个饶有意味的眼神,风一般地又钻回了器材室。

顾欢此言一出,大殿之中的巴山剑派众位长老同时保持了沉默。应申心中想到:“看来你巴山剑派早就是有着跟我龙鳌岛联合的意思,要不然此时为何没有人出来反对?”应申念及此处,心中又想到:“你们巴山剑派想要在这天地大变之时留下自己的道统,恐怕是难上加难,这一界之中,我们是不允许有任何不是我们的人存在!”

Entity Framework 乐观并发处理


Entity Framework 乐观并发处理

      有一段时间没有更新博客了,今天终于有一些时间,和大家讨论一个Entity Framework 乐观并发处理的问题。首先需要说明的是,这里提到的 “并发” 并不是指的多线程处理,也就是笔者这里要讨论的是另外一个问题场景,这个场景描述如下:

  1. 系统用户A从数据库中取得一条记录Record-1

  2. 系统用户B从数据库中取得同一条记录Record-1

  3. 系统用户B修改记录Record-1,并保存到数据库

  4. 系统用户A修改记录Record-1,并保存到数据库

  这个场景里面的问题是系统用户B对数据路记录Record-1的修改被A的修改冲掉了,这种行为在某些业务场景中是正确的,但是在某些场景中可能会有问题,因为这样的场景中A可能希望感知Record-1的变化,并做出相应的代码策略处理。针对这种场景Entity Framework 专门有一种解决方案,Timestamp或者叫Rowersion,具体实现代码如下, 在需要支持乐观并发的model上增加Timestamp字段,字段的名字叫RowVersion,当然对应的数据库表上也要加上这个字段RowVersion,类型是timestamp, 这样在以上描述的场景发生时,系统就会捕获到相应的异常,从而有机会对这种场景进行相应的业务处理。

 

如果不喜欢Data Annotation,也可以使用 Fluent api 进行标记,具体代码如下,

 

modelBuilder.Entity<Department>().Property(p => p.RowVersion).IsRowVersion();

 

namespace ContosoUniversity.Models
{
    public class Department
    {
[ConcurrencyCheck]
public int DepartmentID { get; set; } [StringLength(50, MinimumLength = 3)] public string Name { get; set; } [DataType(DataType.Currency)] [Column(TypeName = "money")] public decimal Budget { get; set; } [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] [Display(Name = "Start Date")] public DateTime StartDate { get; set; } public int? InstructorID { get; set; } [Timestamp] public byte[] RowVersion { get; set; } public virtual Instructor Administrator { get; set; } public virtual ICollection<Course> Courses { get; set; } } }

 

   try
{ db.Entry(departmentToUpdate).OriginalValues["RowVersion"] = rowVersion; await db.SaveChangesAsync(); return RedirectToAction("Index"); } catch (DbUpdateConcurrencyException ex) { var entry = ex.Entries.Single(); var clientValues = (Department)entry.Entity; var databaseEntry = entry.GetDatabaseValues(); if (databaseEntry == null) { ModelState.AddModelError(string.Empty, "Unable to save changes. The department was deleted by another user."); } else { var databaseValues = (Department)databaseEntry.ToObject(); if (databaseValues.Name != clientValues.Name) ModelState.AddModelError("Name", "Current value: " + databaseValues.Name); if (databaseValues.Budget != clientValues.Budget) ModelState.AddModelError("Budget", "Current value: " + String.Format("{0:c}", databaseValues.Budget)); if (databaseValues.StartDate != clientValues.StartDate) ModelState.AddModelError("StartDate", "Current value: " + String.Format("{0:d}", databaseValues.StartDate)); if (databaseValues.InstructorID != clientValues.InstructorID) ModelState.AddModelError("InstructorID", "Current value: " + db.Instructors.Find(databaseValues.InstructorID).FullName); ModelState.AddModelError(string.Empty, "The record you attempted to edit " + "was modified by another user after you got the original value. The " + "edit operation was canceled and the current values in the database " + "have been displayed. If you still want to edit this record, click " + "the Save button again. Otherwise click the Back to List hyperlink."); departmentToUpdate.RowVersion = databaseValues.RowVersion; } }

 

当然Timestamp字段不是必须单独添加的,也可以使用model上的已有字段,假设这个字段是DepartmentID,我们可以使用ConcurrencyCheck注解进行标记,当然也可是使用Fluent api 进行标记,具体代码如下,

modelBuilder.Entity<Person>().Property(p => p.DepartmentID).IsConcurrencyToken();

 

总结

本文详细描述了一种Entity Framework 乐观并发处理的解决方案,并且通过Data Annotation和Fluent api 两种方式进行了详细的说明,希望对大家有所帮助。

当前文章:http://zxqss.com/forum.php?mod=viewthread&tid=75531

发布时间:2019-02-17 07:01:45

1到13扑克翻牌怎么玩 老友漳浦麻将 德州扑克教学视频 最新喜来乐棋牌游戏 一花主播德州下载 自己做棋牌游戏平台 塔克世界官网 正规棋牌游戏技巧

编辑:海陵

我要说两句: (0人参与)

发布