Entity Framework中的并发性
Entity Framework默认支持乐观并发。EF将实体数据保存到数据库中,假设自加载实体以来没有更改相同的数据。如果它发现数据已更改,则抛出异常,您必须在再次尝试保存数据之前解决冲突。
要使用EF 6 database-first方法处理并发性,请在SQL Server中的表中创建一个数据类型为rowversion(时间戳)的列。rowversion(同义词时间戳)数据类型只是一个递增的二进制数,对于在包含rowversion列的表上执行的每次插入和更新操作,该二进制数都会递增。
让我们为Student实体实现并发性。
为了检查Student实体的并发性,Student表必须有一个rowversion列。因此,在Student表中创建一个名为RowVersion的新列,该列具有时间戳数据类型(时间戳是RowVersion的同义词数据类型),如下所示:
现在,创建一个新的实体数据模型,如创建实体数据模型章节所示,或者,如果你已经有一个EDM,那么通过右键单击designer -> update Model From Database -> Refresh Student表来更新它。您将看到在设计器视图中的Student实体中添加了RowVersion属性。
现在,你需要通过右键单击设计器上Student实体的RowVersion属性来设置并发模式为固定,选择属性并在属性窗口中将并发模式设置为固定,如下所示:
EF API现在将在每个UPDATE命令的where子句中包含这个RowVersion列,如果RowVersion值与数据库中的现有值不同,那么它将抛出DbUpdateConcurrencyException。
下面的例子演示了如何处理并发异常:
Student student = null;
using (var context = new SchoolDBEntities())
{
student = context.Students.First();
}
//编辑学生姓名
Console.Write("Enter New Student Name:");
student.StudentName = Console.ReadLine(); //从控制台读取学生姓名
using (var context = new SchoolDBEntities())
{
try
{
context.Entry(student).State = EntityState.Modified;
context.SaveChanges();
Console.WriteLine("Student saved successfully.");
}
catch (DbUpdateConcurrencyException ex)
{
Console.WriteLine("Concurrency Exception Occurred.");
}
}
假设有两个用户执行上面的代码。User1和User2都得到相同的Student实体。现在,User1输入一个新的学生名,并将其保存在User2之前。因此,User1将得到“学生保存成功”消息,而User2将得到“并发异常发生”。
参考
https://www.entityframeworktutorial.net/
https://msdn.microsoft.com/