2011-03-17 2 views
172

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

Чтобы очистить вещи:

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

ответ

355

В то время как вы находитесь в режиме отладки внутри catch {...} блока открыть окно "QuickWatch" (Ctrl + альт + д) и вставить туда:

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

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

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

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

Это лучше, чем другой ответ :) – Doug

+93

Если у вас нет блока catch, вы можете заменить 'ex' на' $ exception' и получить тот же результат. – Ecyrb

+0

также убедитесь, что вы заменили 'ex' на w/e ваш' catch (Exception THIS) 'is – Eonasdan

4

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

public string Comment {get; set;} 

Тогда в методе семян в перекрытом инициализаторе, у меня был совсем немного длинным (около 600 писем) комментарий

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

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

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

+0

Ну, что я спрашивал, как получить точное имя свойства, которое нарушает модель. Хотя мне удалось преодолеть проблему, о которой вы говорили, используя [StringLength (Int32.MaxValue)] как атрибут для моего свойства (как это было предложено нами в Ladislav Mrnka, я говорил об этом в этом вопросе http://stackoverflow.com/questions/5346155/ef-code-first-4-1-doesnt-support-nvarcharmax-at-all) Powodzenia! =) –

+0

Это было брошено, когда я добавил новое свойство своей модели в 4.1. Работала отлично в 4.1. Weird. Решено путем добавления аннотации ко всем свойствам модели. –

122

Вы можете попробовать это в блоке 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); 
     } 
    } 
} 
+1

именно то, что мне нужно. большое спасибо! –

+8

См. Мой ответ, если вы не хотите менять какой-либо код. – GONeale

1

Я нашел, что это полезно создать оболочку 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 

, а затем изменили 'entities.SaveChanges()' до 'SaveChanges (лиц)' во всем моем проекте

8

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

просто добавить этот метод к основным 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() метод контекста вашего, и вы получите список разделенной запятой, содержащий все ошибки проверки сущности.

желающий это поможет.

Смежные вопросы