исключение optimisticconcurrency было обнаружено при обновлении отношения сущностей с использованием заглушек - PullRequest
0 голосов
/ 25 января 2011

Этот код дает мне оптимистическое исключение параллельной валюты было поймано. Я просто использую объект-заглушку для получения существующей записи и пытаюсь обновить пару значений. Я не уверен, как разрешить исключение. Любая помощь очень ценится:

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 Ответ

2 голосов
/ 26 января 2011

EF по умолчанию использует оптимистическую модель параллелизма, что означает, что блокировки данных в источнике не удерживаются между моментом запроса данных и их обновлением. Поэтому он не проверяет наличие каких-либо конфликтов перед сохранением изменений в базе данных. При любых конфликтах возникает исключение OptimisticConcurrencyException (для получения дополнительной информации см. Как: управлять параллелизмом данных в контексте объекта ).

Хорошей практикой (когда вы делаете обновления в сценарии с высокой степенью параллелизма) довольно часто вызывать Обновить . В этом случае попробуйте использовать 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.

Решение очень простое, прикрепите ваши объекты до того, как выполнит какие-либо операции / запросы в вашем 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();

} * * тысяча двадцать-один }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...