2011-03-17 9 views
172

Mam sytuacji gdzie mam inicjowanie mój model w DatabaseInitializer() dla EF 4.1 i dostać ten przykry błąd "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details." Więc idę do tego EntityValidationErrors i znajduje się pole, które daje mi {System.Data.Entity.Validation.DbEntityValidationResult} brak informacji o tym, którego pola nie można zainicjować. Czy istnieje sposób, aby uzyskać więcej informacji na temat tego błędu?Pierwsze wpisać dokładny błąd z DbValidationException

Aby wyczyścić rzeczy:

wiem jak rozwiązać ten problem długości łańcuch. Pytam, jak uzyskać dokładną nazwę pola, która łamie model.

Odpowiedz

355

Gdy jesteś w trybie debugowania w bloku catch {...} otworzyć okno "QuickWatch" (Ctrl + alt + q) i wklej tam:

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

ten pozwoli ci przejść do drzewa ValidationErrors. To najprostszy sposób, w jaki znalazłem, aby uzyskać natychmiastowy wgląd w te błędy.

dla Visual 2012+ użytkowników, którzy dbają tylko o pierwszym błędem i może nie mają catch blok, można nawet zrobić:

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

To jest lepsze niż druga odpowiedź :) – Doug

+93

Jeśli nie masz bloku catch, możesz zamienić 'ex' na' $ exception' i uzyskać ten sam wynik. – Ecyrb

+0

również upewnij się, że zastąpiłeś 'ex' z w/e twoim' catch'em (Exception THIS) 'jest – Eonasdan

4

Cóż, miałem ten sam problem. . Mój model pracował dobrze w EF CTP5 ale nie udało się zbudować w 4.1 z tego samego błędu „” Weryfikacja nie powiodła się dla jednego lub większej liczby podmiotów”, gdy próbowałem go initalize zorientowali się, że miałem właściwość:

public string Comment {get; set;} 

Następnie w metodzie nasion w overrided inicjatora, miałem dość trochę długo (około 600 listów) komentarz

myślę, że chodzi o to:.. w EF 4.1 masz ustawić adnotacji danych wyraźnie w niektórych przypadkach dla mnie ustawienie :

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

pomógł. To dziwne, ponieważ CTP5 nie miał z tym problemów.

+0

Cóż, o co pytałem, to jak uzyskać dokładną nazwę właściwości, która łamie model. Mimo to udało mi się przezwyciężyć problem, który stwierdziłaś za pomocą [StringLength (Int32.MaxValue)] jako atrybutu dla mojej własności (jak to sugerował Ladislav Mrnka i rozmawiałem o tym w tym pytaniu http://stackoverflow.com/questions/5346155/ef-code-first-4-1-doesnt-support-nvarcharmax-at-all) Powodzenia! =) –

+0

Zostało to zgłoszone, gdy dodałem nową właściwość do mojego modelu w wersji 4.1. Pracował idealnie w 4.1 wcześniej. Dziwne. Rozwiązano przez dodanie adnotacji do wszystkich właściwości w modelu. –

122

Możesz spróbować tego w bloku 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

dokładnie to, czego potrzebowałem. wielkie dzięki! –

+8

Zobacz moją odpowiedź, jeśli nie chcesz zmieniać żadnego kodu. – GONeale

1

Uważam, że warto stworzyć SaveChanges owijkę, która sprawia, że ​​te EntityValidationErrors więcej czytelny:

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 

a następnie zmieniło 'entities.SaveChanges()' do 'SaveChanges (podmiotów)' w całym moim projekcie

8

najlepszym Solu Moim zdaniem, ten rodzaj błędów należy rozpatrywać w sposób scentralizowany.

wystarczy dodać tę metodę do głównego DbContext klasy:

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); 
    } 
} 

ten zastąpi SaveChanges() metodę kontekstu i dostaniesz przecinek listę zawierającą wszystkie błędy sprawdzania poprawności podmiot rozdzielone.

mam nadzieję, że to będzie pomocne.