乐观并发
乐观并发模式是指乐观的尝试将实体保存到数据库中,以期数据自实体加载后未曾改变。单若数据确实发生了更改,则将引发异常(DbUpdateConcurrencyException
),必须先解决冲突,然后再尝试保存。
解决乐观并发模式的异常
static void Main(string[] args)
{
using (var db = new SchoolEntities2())
{
Authors author = db.Authors.Find(1);
Console.WriteLine("name:"+author.Name);
db.Entry(author).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
/* 方式一:使用reload会使用数据库中的当前值覆盖实体中的值(包括当前值与原始值)
var entry = ex.Entries.Single();
Console.WriteLine("CurrentValues:" + entry.CurrentValues.GetValue<string>("Name"));
Console.WriteLine("OriginalValues:" + entry.OriginalValues.GetValue<string>("Name"));
entry.Reload();//重新从数据库中获取
Console.WriteLine("CurrentValues2:" + entry.CurrentValues.GetValue<string>("Name"));
Console.WriteLine("OriginalValues2:" + entry.OriginalValues.GetValue<string>("Name"));
*/
//方式二:可以选择性覆盖实体中的值
var entry = ex.Entries.Single();
Console.WriteLine("CurrentValues:" + entry.CurrentValues.GetValue<string>("Name"));
Console.WriteLine("OriginalValues:" + entry.OriginalValues.GetValue<string>("Name"));
//将重新从数据库中获取的值保存到当前实体的原始值中
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
// entry.CurrentValues.SetValues(entry.GetDatabaseValues());
Console.WriteLine("CurrentValues2:" + entry.CurrentValues.GetValue<string>("Name"));
Console.WriteLine("OriginalValues2:" + entry.OriginalValues.GetValue<string>("Name"));
}
catch (Exception ex)
{ }
}
Console.ReadLine();
}
当然也可以使用实体类型的实例执行此操作。可使用 DbPropertyValues
的 ToObject
和 SetValues
方法实现这一点。例如:
var entry = ex.Entries.Single();
var databaseValue = entry.GetDatabaseValues();
var databaseValueAsAuthor = (Authors)databaseValue.ToObject();
entry.OriginalValues.SetValues(databaseValueAsAuthor);
注意:需要将EF中的并发模式设为Fixed ;EF仅支持乐观并发模式
乐观并发与悲观并发的区别:悲观并发在修改数据时,其它用户不需进行操作(包括读取),乐观模式可以。