2011-01-25 33 views
0

此代码给了我optimisticconcurrencyexception被捕获。我只是使用存根实体来获取现有记录并尝试更新一对值。我不知道如何解决异常。任何帮助是非常赞赏:使用存根实体更新实体关系时,发现了optimisticconcurrencyexception

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(); 
} 

回答

1

EF,默认情况下,使用了乐观并发模型,这意味着锁定未在当数据被查询,当它被更新的源举行的数据。因此,在保存对数据库的更改之前,不会检查是否存在任何冲突。对于任何冲突,都会引发OptimisticConcurrencyException(有关更多信息,请检查How to: Manage Data Concurrency in the Object Context)。

很好的做法(在高并发情况下进行更新时)经常调用Refresh。在这种情况下,尝试将它们发送到数据库中,这样使用前ClientWins的RefreshMode以刷新在客户端存储的值:

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缓存了。

该解决方案非常简单,在您的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(); 

}
}

+0

谢谢,但它未能在AttachTo方法。它说“ObjectStateManager中已经存在具有相同键的对象,ObjectStateManager不能使用同一个键跟踪多个对象。”任何想法如何解决? – obautista 2011-01-26 06:16:08