Uzyskiwanie dokładnego typu błędu z DbValidationException

Mam sytuację, w której inicjalizuję mój model w DatabaseInitializer () dla EF 4.1 i dostaję ten irytujący błąd "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.", więc przechodzę do tego EntityValidationErrors i jest tam pole {System.Data.Entity.Validation.DbEntityValidationResult}, które nie daje mi żadnych informacji o tym, jakiego pola nie udało się zainicjować. Czy istnieje sposób, aby uzyskać więcej informacji o tym błędzie?

Aby wszystko wyjaśnić:

Wiem, jak rozwiązać problem długości łańcucha. Pytam tylko, jak uzyskać dokładną nazwę pola, która jest łamanie modelu.

Author: leppie, 2011-03-18

5 answers

Gdy jesteś w trybie debugowania w bloku catch {...} Otwórz okno " QuickWatch "(ctrl+alt+q ) i wklej tam:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors
To pozwoli Ci wwiercić się w drzewo. To najprostszy sposób, jaki znalazłem, aby uzyskać natychmiastowy wgląd w te błędy.

Dla użytkowników Visual 2012+, którzy dbają tylko o pierwszy błąd i mogą nie mieć bloku catch, możesz nawet zrobić:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage
 363
Author: GONeale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-07 12:08:59

Możesz spróbować 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);
        }
    }
}
 122
Author: Trent Scholl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-23 04:00:42

Moim zdaniem najlepszym rozwiązaniem jest scentralizowana obsługa tego typu błędów.

Wystarczy dodać tę metodę do głównej klasy 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);
    }
}

To nadpisze metodę kontekstu SaveChanges() i otrzymasz oddzieloną przecinkami listę zawierającą wszystkie błędy walidacji encji.

Mam nadzieję, że to pomoże.
 9
Author: Chtiwi Malek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-22 10:35:11

Cóż, miałem ten sam problem. Mój model działał dobrze w EF CTP5, ale nie udało się zbudować w 4.1 z tym samym błędem ""Walidacja nie powiodła się dla jednego lub więcej podmiotów", gdy próbowałem ją initalizować. Domyśliłem się, że mam własność:

public string Comment {get; set;}

Następnie w metodzie seed w nadrzędnym inicjalizatorze miałem dość długi (około 600 liter) komentarz.

Myślę, że chodzi o to, że w EF 4.1 masz aby ustawić adnotacje do danych jawnie w niektórych przypadkach. Dla mnie ustawienie:

[StringLength(4000)] 
public string Comment {get; set;}
Pomógł. On dziwne, bo CTP5 nie miał z tym żadnych problemów.
 4
Author: Wojciech Kotlinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-18 18:55:34

Uznałem, że przydatne jest stworzenie wrappera SaveChanges, który sprawia, że EntityValidationErrors jest bardziej 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 zmieniono ' encje.SaveChanges () 'do' SaveChanges(entities) ' w całym moim projekcie

 1
Author: smirkingman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-16 13:00:37