Подтвердить что ты не робот

Поиск причины DBUpdateException

При вызове DbContext.SaveChanges я получаю исключение DbUpdateException:

"В EntityFramework.dll появилось необработанное исключение типа" System.Data.Entity.Infrastructure.DbUpdateException ". Дополнительная информация: при обновлении записей произошла ошибка. Подробнее см. внутреннее исключение.

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

4b9b3361

Ответ 1

Когда кажется, что реальное исключение теряется где-то, лучше всего ломаться на каждое исключение. Независимо от того, поймал ли он или проглотил где-нибудь, вне или вне досягаемости, отладчик сломается и позволит вам увидеть, что происходит.

Для получения дополнительной информации см. эту ссылку MSDN:

Как разбить, когда выбрасывается исключение

Ответ 2

Это мое переопределение SaveChanges. Это дает мне полезное место для размещения контрольных точек:

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {
            foreach (var eve in e.EntityValidationErrors)
            {
                Debug.WriteLine(@"Entity of type ""{0}"" in state ""{1}"" 
                   has the following validation errors:",
                    eve.Entry.Entity.GetType().Name, 
                    eve.Entry.State);
                foreach (var ve in eve.ValidationErrors)
                {
                    Debug.WriteLine(@"- Property: ""{0}"", Error: ""{1}""",
                        ve.PropertyName, ve.ErrorMessage);
                }
            }
            throw;
        }
        catch(DbUpdateException e)
        {
           //Add your code to inspect the inner exception and/or
           //e.Entries here.
           //Or just use the debugger.
           //Added this catch (after the comments below) to make it more obvious 
           //how this code might help this specific problem
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
            throw;
        }
    }

Ссылка:

Не удалось выполнить проверку для одного или нескольких объектов. Дополнительную информацию см. В разделе Свойство EntityValidationErrors

Ответ 3

Здесь мое переопределение SaveChanges, показывающее дополнительный код для обработки исключения DbUpdateException (в соответствии с вопросом).

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException vex)
        {
            var exception = HandleDbEntityValidationException(vex);
            throw exception;
        }
        catch(DbUpdateException dbu)
        {
            var exception = HandleDbUpdateException(dbu);
            throw exception;
        }
    }

    private Exception HandleDbUpdateException(DbUpdateException dbu)
    {
        var builder = new StringBuilder("A DbUpdateException was caught while saving changes. ");

        try
        {
            foreach (var result in dbu.Entries)
            {
                builder.AppendFormat("Type: {0} was part of the problem. ", result.Entity.GetType().Name);
            }
        }
        catch (Exception e)
        {
            builder.Append("Error parsing DbUpdateException: " + e.ToString());
        }

        string message = builder.ToString();
        return new Exception(message, dbu);
    }

Я не сделал код регистрации очень конкретным, но он улучшает стандартное сообщение об ошибке:

The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.

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

Ответ 4

Основываясь на ответе Колина, можно получить полную подробную информацию об отказе персистентности EF следующим образом:

public bool SaveChangesEx()
{
    try
    {
        SaveChanges();
        return true;
    }
    catch (DbEntityValidationException exc)
    {
        // just to ease debugging
        foreach (var error in exc.EntityValidationErrors)
        {
            foreach (var errorMsg in error.ValidationErrors)
            {
                // logging service based on NLog
                Logger.Log(LogLevel.Error, $"Error trying to save EF changes - {errorMsg.ErrorMessage}");
            }
        }

        throw;
    }
    catch (DbUpdateException e)
    {
        var sb = new StringBuilder();
        sb.AppendLine($"DbUpdateException error details - {e?.InnerException?.InnerException?.Message}");

        foreach (var eve in e.Entries)
        {
            sb.AppendLine($"Entity of type {eve.Entity.GetType().Name} in state {eve.State} could not be updated");
        }

        Logger.Log(LogLevel.Error, e, sb.ToString());

        throw;
    }
}

Помимо ошибок проверки, исключение для обновления выводит как общую ошибку, так и контекстную информацию.

Примечание. Для работы этого кода требуется С# 6.0, так как он использует нулевое распространение и интерполяцию строк.

Ответ 5

У меня была такая же ошибка: "Преобразование типа данных datetime2 в тип данных datetime привела к внеурочному значению.\r\nПриложение завершено".

Я положил поле значения Datetime как это Datetime.Now

var person = new Person
            {
               FirstName = "Sebastian",
               LastName = "Back",
               **BirthDate = DateTime.Now,**
               IsActive = true,
            };

Ответ 6

Я получил ту же ошибку и решил вот так:

У меня есть поле, тип данных которого datetime, и я знаю, что устанавливаю его без назначенного свойства datetime. Поэтому я меняю его на " Datetime.Now", тогда я вижу, что проблема решена и она была сохранена succesfuly

Ответ 7

В моем случае я использовал Хранимую процедуру для добавления объекта в БД. Мой SP дает ошибку времени выполнения, из-за которой я получал эту ошибку в С#. Я исправил SP, и EF работал отлично. Поэтому, если вы используете SP для добавления, редактирования, удаления или обновления в EF, проверьте, работает ли соответствующий sp.