这段代码给了我optimisticconcurrencyexception被抓住了。我只是使用Stub Entity来获取现有记录并尝试更新几个值。我不知道如何解决这个异常。非常感谢任何帮助:
using (MiscEntities ctx = new MiscEntities())
{
var m = ctx.Rates.FirstOrDefault(m => m.UserId == UserIdGuid);
DataAccess.Rate oldDbRate = new DataAccess.Rate { RatingId = m.RatingId };
ctx.AttachTo("Rates", dbRate);
dbRate.Rating = Rating;
dbRate.DateLastModified = DateTime.Now;
ctx.SaveChanges();
}
答案 0 :(得分:2)
默认情况下,EF使用乐观并发模型,这意味着在查询数据和更新数据之间,源中的数据不会保留锁。因此,在保存对数据库的更改之前,它不会检查是否存在任何冲突。任何冲突都会引发OptimisticConcurrencyException(有关更多信息,请查看How to: Manage Data Concurrency in the Object Context)。
这是一种很好的做法(当您在高并发方案中进行更新时)经常调用Refresh。在这种情况下,尝试使用RefreshMode ClientWins来刷新客户端存储中的值,然后再将它们发送到数据库,如下所示:
using (MiscEntities ctx = new MiscEntities())
{
try
{
var m = ctx.Rates.FirstOrDefault(m => m.UserId == UserIdGuid);
DataAccess.Rate oldDbRate = new DataAccess.Rate { RatingId = m.RatingId };
ctx.AttachTo("Rates", dbRate);
dbRate.Rating = Rating;
dbRate.DateLastModified = DateTime.Now;
ctx.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
ctx.Refresh(RefreshMode.ClientWins, dbRate);
ctx.SaveChanges();
}
}
编辑:在更多阅读并重新阅读该错误消息后,您无法将对象附加到ObjectContext,该对象已经已经被ObjectStateManager缓存。 / p>
解决方案非常简单,在之前附加对象在ObjectContext中执行任何操作/查询。这样可以防止任何双重跟踪请求。如果ObjectContext稍后需要您的实体,它将检索您之前附加的实例,并且您很高兴。看看这段代码,看看它是否有帮助(抱歉,目前没有打开Visual Studio 2010)
using (MiscEntities ctx = new MiscEntities())
{
try
{
ctx.AttachTo("Rates", dbRates);
var m = ctx.Rates.FirstOrDefault(m => m.UserId == UserIdGuid);
DataAccess.Rate oldDbRate = new DataAccess.Rate { RatingId = m.RatingId };
dbRate.Rating = Rating;
dbRate.DateLastModified = DateTime.Now;
ctx.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
ctx.Refresh(RefreshMode.ClientWins, dbRate);
ctx.SaveChanges();
}
}