Обработка исключений SaveChanges в цикле

2

В Entity Framework существует несколько условий, которые обрабатываются на уровне базы данных и передаются обратно в EF как исключения в Context.SaveChanges().

Если вы выполняете создание новых объектов в цикле, вы можете обработать исключение через стандартный блок "Try Catch", но как вы очистите проблемную сущность от очереди SaveChanges()?

Например (перемещение SaveChanges вне цикла не имеет положительного эффекта, поэтому его показано здесь в цикле):

while(i < 1000)
{
    MyEntity Wibble = new MyEntity();
    Wibble.Name = "Test " + i.ToString();

    Context.AddToTests(Wibble);
    Context.SaveChanges();

}

Если по какой-то причине уже существует Wibble, который приводит к сбою вставки в уникальном ограничении в базе данных, я могу обрабатывать непосредственное исключение в цикле.

Однако на следующей итерации он снова терпит неудачу, потому что проблемный экземпляр Wibble все еще существует в очереди SaveChanges - как вы должны справиться с этим?

Вы можете, конечно, проверить заранее, если мы создаем дублирующий Wibble, но это приводит к двум обратным поездкам в базу данных. Я не против обработки исключения, я просто хочу, чтобы вас узнали об этой проблеме, проигнорируйте эту запись и перейдем к ней.

Мысли? Я делаю это неправильно?

EDIT:

Я решил немедленную проблему, но только когда вы выполняете Context.SaveChanges() в цикле. Если вы просто вызываете SaveChanges() один раз, за ​​пределами цикла, мое решение не работает - может ли кто-нибудь предложить альтернативный метод, который будет работать?

  • 0
    Просто комментарий: Вы должны сохранить изменения вне цикла, чтобы у вас была только одна поездка в базу данных вместо тысячи.
Теги:
entity-framework

1 ответ

2
Лучший ответ

Как обычно, я решил в течение 15 минут спросить кого-нибудь:)

Решение заключается в удалении объекта объекта из ObjectStateManager при обработке исключения, что позволяет продолжить цикл:

while(i < 1000)
{
    MyEntity Wibble = new MyEntity();
    Wibble.Name = "Test " + i.ToString();

    Context.AddToTests(Wibble);

    try
    {
        Context.SaveChanges();
    }
    catch
    {
        Context.ObjectStateManager.GetObjectStateEntry(Wibble).Delete();
    }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню