Как я могу игнорировать DbUpdateConcurrencyException с моим кодом Entity Framework? - PullRequest
10 голосов
/ 17 февраля 2011

Можно ли как-нибудь сказать EF не беспокоиться о количестве строк, которые DELETE или UPDATE делают или не делают?

Я пытаюсь удалить строку из базы данных, но поскольку строка не существует, EF выдает исключение: DbUpdateConcurrencyException .. говоря, что 0 строк затронуто . Это правильно -> строки не были удалены. Но это совершенно нормально .. потому что нет данных.

Я действительно не хочу совершать поездку в оба конца в БД, чтобы посмотреть, существует ли эта строка ... и если да, то попробуйте и удалите ее.

Если я попытаюсь проглотить исключение в блоке try / catch, то остальные элементы, которые будут удалены, НЕ отправляются в БД, когда я пытаюсь SaveChanges() ..., что плохо.

например.

Delete(new Foo(1));
Delete(new Foo(2));
Delete(new Foo(3));
SaveChanges(); // <-- Throws the exception.

// DB Trace : DELETE FROM Foo WHERE Id = 1;

и все ... нет никаких следов, показывающих запись 2 или 3, пытающуюся удалить .. потому что исключение останавливает все: (

Есть идеи?

UPDATE

Как работает Delete? Вот код ... (упрощенный и строго типизированный)

public void Delete(Foo foo)
{
    if (foo == null)
    {
        throw new ArgumentNullException("foo");
    }

    Foo attachedEntity = Context.Set<Foo>().Local.FirstOrDefault(x => x.Id > 0);

    if (attachedEntity != null)
    {
        // Entity already in object graph - remove entity.
        Context.Set<Foo>().Remove(attachedEntity);
    }
    else
    {
        // Entity not in object graph, attach and set EntityState to Deleted.
        Context.Entry(foo).State = EntityState.Deleted;
    }
}

Ответы [ 2 ]

2 голосов
/ 17 февраля 2011

Я думаю, что поведение EF правильное - просто вы должны выполнять команды только для объектов, которые присутствуют в БД.Это не для таких сценариев, как: «Я попробую, и мы увидим ...».Если вы не можете быть уверены в том, что объект существует в БД, и вы не хотите совершать туда-обратно (что я считаю лучшей идеей, поскольку удаление отдельного объекта может иметь несколько других подводных камней, особенно если объект участвует в независимых ассоциациях), вам следует использоватьDbContext.Database.SqlCommand и запустите процедуру сохранения.

Описан правильный способ обработки DbUpdateConcurrencyException здесь => После каждого исключения вы должны разрешать конфликты (в вашем случае это означает удаление проблемной сущности изDbContext) и снова выполните SaveChanges.

0 голосов
/ 02 августа 2012

Фактически вы можете игнорировать подобные проблемы, установив:

db.Configuration.ValidateOnSaveEnabled = false;

Где db - это экземпляр DbContext.

Очевидно, вы должны знать, чтовы делаете, когда делаете это, но, опять же, большинство подходов к обновлению базы данных, которые не являются EF, не имеют никакого отслеживания / проверки изменений и просто выдают обновление / вставку / удаление в базу данных наивно, не проверяя ничего сначала, поэтомувы просто говорите EF вести себя так.

...