猿教程 Logo

Entity Framework 并发

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效:去购买

实体框架默认支持乐观并发。 在乐观并发中,EF将实体保存到数据库,假设自实体加载以来相同的数据没有改变。 如果它确定数据已更改,则会抛出异常,您必须解决冲突,然后再尝试保存。

让我们看看如何使用Student实体处理乐观并发。

首先,您需要在Student表中有一个rowversion列,以便使用Student实体处理并发。 Rowversion是SQL Server中的一种数据类型,每当在表中执行插入或更新操作时,它都会自动生成唯一的二进制数。 rowversion数据类型只是一个递增的数字。 Rowversion类似于timestamp数据类型。

在具有时间戳数据类型的学生表中创建新列RowVersion,如下所示:


注意:在插入和更新操作期间,RowVersion的值将由数据库自动添加和更新。

现在,创建一个新的实体数据模型,如创建实体数据模型部分所示,或者如果您已经有一个EDM,然后通过右键单击设计器 - >更新模型从数据库 - >刷新Student表更新它。 现在,您将看到在实体中添加的RowVersion属性。

然后,您需要通过右键单击学生实体中的RowVersion属性(右键单击RowVersion属性而不是学生实体) - >选择属性,将并发模式设置为固定。 在属性窗口中将并发模式从无更改为固定,如下所示:


EF现在将在where子句中包括RowVersion列,每当您执行更新操作,并且rowversion值与where子句不同时,它将抛出DbUpdateConcurrencyException。

以下代码显示User1和User2获得同一个学生并同时更新学生姓名:

运行结果:

Student student1WithUser1 = null; 
Student student1WithUser2 = null;

//User 1 gets student
using (var context = new SchoolDBEntities())
{
    context.Configuration.ProxyCreationEnabled = false;
    student1WithUser1 = context.Students.Where(s => s.StudentID == 1).Single();
}
//User 2 also get the same student
using (var context = new SchoolDBEntities())
{
    context.Configuration.ProxyCreationEnabled = false;
    student1WithUser2 = context.Students.Where(s => s.StudentID == 1).Single();
}
//User 1 updates Student name
student1WithUser1.StudentName = "Edited from user1";

//User 2 updates Student name
student1WithUser2.StudentName = "Edited from user2";

User1在User2之前保存他的更改。 因此,当user2尝试保存更改时,他将获得并发排除:

运行结果:

//User 1 saves changes first
using (var context = new SchoolDBEntities())
{
    try
    {
        context.Entry(student1WithUser1).State = EntityState.Modified;
        context.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        Console.WriteLine("Optimistic Concurrency exception occured");
    }
}

//User 2 saves changes after User 1. 
//User 2 will get concurrency exection 
//because CreateOrModifiedDate is different in the database 
using (var context = new SchoolDBEntities())
{
    try
    {
        context.Entry(student1WithUser2).State = EntityState.Modified;
        context.SaveChanges();
    }
    catch (DbUpdateConcurrencyException ex)
    {
        Console.WriteLine("Optimistic Concurrency exception occured");
    }
}

Code-First中的并发:

在代码优先模式中,您可以使用[Timestamp]属性在代码中创建时间戳属性。 确保属性类型为byte [],因为timestamp是C#中的二进制。

如果属性标记有Timestamp属性,则EF在更新操作期间会在where子句中包括该属性。

您可以多种方式解决并发异常。 有关如何解决乐观并发的详细信息,请访问msdn

阿里云服务器,每月低至7.8元,项目演示即建站必备,比腾讯云更便宜,并且不需学生认证,从此链接购买有效: 去购买


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/entity/Concurrency .html