使用存根实体更新实体关系时捕获了optimisticconcurrencyexception [英] optimisticconcurrencyexception was caught when updating entity relation using stub entities

查看:117
本文介绍了使用存根实体更新实体关系时捕获了optimisticconcurrencyexception的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码使我被乐观的concurrencyexception捕获。我只是在使用存根实体来获取现有记录并尝试更新几个值。我不确定如何解决该异常。非常感谢您的帮助:

This code is giving me optimisticconcurrencyexception was caught. I am simply using a Stub Entity to get an existing record and trying to update a couple values. I am not sure how to resolve the exception. Any help is very much appreciated:

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


推荐答案

EF默认情况下使用乐观并发模型,这意味着在查询数据和更新数据之间不会对源中的数据保持锁定。因此,在将更改保存到数据库之前,它不会检查是否存在任何冲突。发生任何冲突时,都会引发OptimisticConcurrencyException(有关更多信息,请参见如何:在对象上下文中管理数据并发

EF, by default, uses an optimistic concurrency model, meaning that locks are not held on data in the source between when the data is queried and when it is updated. So it doesn't check for any conflicts before saving changes to the database. With any conflicts an OptimisticConcurrencyException is raised (for more information check out How to: Manage Data Concurrency in the Object Context).

(在高并发情况下进行更新时)调用刷新经常。在这种情况下,请尝试使用 RefreshMode ClientWin可以刷新客户端存储中的值,然后再将其发送到数据库,如下所示:

It's good practice (when you make updates in a high concurrency scenario) to call Refresh quite often. In this case try using a RefreshMode of ClientWins to to refresh the values in the client store before sending them to the database, like this:

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

After more reading, and re-reading that error message it makes sense, you cannot attach an object to an ObjectContext is that object has already that has already been cached by the ObjectStateManager.

该解决方案非常简单,请在对象上下文中进行任何操作/查询之前,先附加对象。这使您可以防止任何双重跟踪请求。如果ObjectContext以后需要您的Entity,它将检索您之前附加的实例,您可以使用。看看这段代码,看看是否有帮助(对不起,暂时没有打开Visual Studio 2010)

The solution is real simple, attach your objects before doing any operations/query in your ObjectContext. This allows you to prevent any double-tracking requests. If the ObjectContext needs your Entity later, it will retrieve the instance you attached before and you're good to go. Take a look at this code and see if it helps (Sorry don't have Visual Studio 2010 opened right now)

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

}

}

}
}

这篇关于使用存根实体更新实体关系时捕获了optimisticconcurrencyexception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆