Получение точного типа ошибки в DbValidationException

у меня есть ситуация, когда я инициализирую свою модель в DatabaseInitializer () для EF 4.1 и получаю эту раздражающую ошибку "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." Итак, я иду к этому EntityValidationErrors и есть поле {System.Data.Entity.Validation.DbEntityValidationResult} что не дает мне никакой информации о том, какое поле он не смог инициализировать. Есть ли способ получить дополнительную информацию об этой ошибке?

очистить вещи:

Я знаю как исправить проблему длину строки. Я спрашиваю, как мне получить точное имя поля, которое нарушает модель.

5 ответов


пока вы находитесь в режиме отладки в catch {...} блок откройте окно "QuickWatch" (ctrl+alt+q) и вставить туда:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

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

для пользователей Visual 2012+, которые заботятся только о первой ошибке и не может иметь catch блок, вы даже можете сделать:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage

вы можете попробовать это в блоке try/catch?

catch (DbEntityValidationException dbEx)
{
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
        }
    }
}

лучшим решением, на мой взгляд,является централизованная обработка такого рода ошибок.

просто добавьте этот метод в main DbContext класс :

public override int SaveChanges()
{
    try
    {
        return base.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
        throw new DbEntityValidationException(errorMessages);
    }
}

Это перезапишет ваш контекст SaveChanges() метод, и вы получите список, разделенный запятыми, содержащий все ошибки проверки сущности.

надеюсь, что это полезно.


Ну, у меня была такая же проблема. Моя модель хорошо работала в EF CTP5, но не смогла построить в 4.1 с той же ошибкой ""проверка не удалась для одного или нескольких объектов", когда я попытался ее инициализировать. Я понял, что у меня есть собственность:

public string Comment {get; set;}

затем в методе seed в переопределенном инициализаторе у меня был довольно длинный (около 600 букв) комментарий.

Я думаю, что дело в том, что в EF 4.1 вы есть для явного задания аннотаций данных в некоторых случаях. Для меня, настройка:

[StringLength(4000)] 
public string Comment {get; set;}

помогло. Это странно, так как CTP5 не имел проблем с этим.


Я нашел полезным создать оболочку SaveChanges, которая делает EntityValidationErrors более читаемым:

Public Sub SaveChanges(entities As Entities)

    Try
        entities.SaveChanges()

    Catch ex As DbEntityValidationException

        Dim msg As New StringBuilder
        msg.AppendLine(ex.Message)

        For Each vr As DbEntityValidationResult In ex.EntityValidationErrors
            For Each ve As DbValidationError In vr.ValidationErrors
                msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage))
            Next
        Next

        Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex)

    End Try

End Sub

и тогда лица изменилось.SaveChanges () " для "SaveChanges (entities)" во всем моем проекте