В 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() один раз, за пределами цикла, мое решение не работает - может ли кто-нибудь предложить альтернативный метод, который будет работать?
Как обычно, я решил в течение 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();
}
}