340 Stimmen

Validierung für eine oder mehrere Entitäten beim Speichern von Änderungen in der SQL Server-Datenbank mit Entity Framework fehlgeschlagen

Ich möchte meine bearbeiten, um Datenbank zu speichern und ich bin mit Entity FrameWork Code-First in ASP.NET MVC 3 / C#, aber ich bin immer Fehler. In meiner Ereignisklasse habe ich die Datentypen DateTime und TimeSpan, aber in meiner Datenbank habe ich Datum bzw. Uhrzeit. Könnte dies der Grund sein? Wie kann ich vor dem Speichern von Änderungen in der Datenbank den entsprechenden Datentyp im Code verwenden?

public class Event
{
    public int EventId { get; set; }
    public int CategoryId { get; set; }
    public int PlaceId { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public DateTime EventDate { get; set; }
    public TimeSpan StartTime { get; set; }
    public TimeSpan EndTime { get; set; }
    public string Description { get; set; }
    public string EventPlaceUrl { get; set; }
    public Category Category { get; set; }
    public Place Place { get; set; }
}

Methode in der Steuerung >>>> Problem bei storeDB.SaveChanges();

// POST: /EventManager/Edit/386        
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
    var theEvent = storeDB.Events.Find(id);

    if (TryUpdateModel(theEvent))
    {
        storeDB.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        ViewBag.Categories = storeDB.Categories.OrderBy(g => g.Name).ToList();
        ViewBag.Places = storeDB.Places.OrderBy(a => a.Name).ToList();
        return View(theEvent);
    }
}

mit

public class EventCalendarEntities : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Place> Places { get; set; } 
}

SQL Server 2008 R2 Datenbank / T-SQL

EventDate (Datatype = date)  
StartTime (Datatype = time)  
EndTime (Datatype = time)  

Http-Formular

EventDate (Datatype = DateTime) e.g. 4/8/2011 12:00:00 AM  
StartTime (Datatype = Timespan/time not sure) e.g. 08:30:00  
EndTime (Datatype = Timespan/time not sure) e.g. 09:00:00  

Serverfehler in der Anwendung '/'.

Validierung für eine oder mehrere Entitäten fehlgeschlagen. Siehe Eigenschaft 'EntityValidationErrors' für weitere Details.

Beschreibung: Während der Ausführung der aktuellen Webanfrage ist eine unbehandelte Ausnahme aufgetreten. Bitte überprüfen Sie den Stack-Trace für weitere Informationen über den Fehler und wo er im Code entstanden ist.

Details zur Ausnahme: System.Data.Entity.Validation.DbEntityValidationException: Validierung für eine oder mehrere Entitäten fehlgeschlagen. Siehe Eigenschaft 'EntityValidationErrors' für weitere Details.

Fehlerquelle:

Line 75:             if (TryUpdateModel(theEvent))
Line 76:             {
Line 77:                 storeDB.SaveChanges();
Line 78:                 return RedirectToAction("Index");
Line 79:             }

Quelldatei: C:\sep\MvcEventCalendar\MvcEventCalendar\Controllers\EventManagerController.cs Zeile: 77

Stack Trace:

[DbEntityValidationException: Validierung für eine oder mehrere Entitäten fehlgeschlagen. Siehe Eigenschaft 'EntityValidationErrors' für weitere Details].

5voto

Dieser Code half mir, mein Problem zu finden, als ich ein Problem mit meinen Entity VAlidation Erros hatte. Es sagte mir das genaue Problem mit meiner Entitätsdefinition. Versuchen Sie folgenden Code, wo Sie storeDB.SaveChanges(); in folgenden Try-Catch-Block abdecken müssen.

  try
{
         if (TryUpdateModel(theEvent))
         {
             storeDB.SaveChanges();
             return RedirectToAction("Index");
         }
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
    Exception raise = dbEx;
    foreach (var validationErrors in dbEx.EntityValidationErrors)
    {
        foreach (var validationError in validationErrors.ValidationErrors)
        {
            string message = string.Format("{0}:{1}", 
                validationErrors.Entry.Entity.ToString(),
                validationError.ErrorMessage);
            // raise a new exception nesting
            // the current instance as InnerException
            raise = new InvalidOperationException(message, raise);
        }
    }
    throw raise;
}

4voto

dan richardson Punkte 3761

Ich habe heute diesen Fehler erhalten und konnte ihn eine Zeit lang nicht lösen, aber dann habe ich erkannt, dass es nach dem Hinzufügen einiger RequireAttribute s in meine Modelle einfügte und feststellte, dass einige Entwicklungsdaten nicht alle erforderlichen Felder ausfüllten.
Also nur ein Hinweis, dass, wenn Sie diesen Fehler erhalten, während der Aktualisierung der Datenbank durch eine Art von Init-Strategie wie DropCreateDatabaseIfModelChanges dann müssen Sie dafür sorgen, dass Ihre die Saatgutdaten alle Attribute der Modelldatenvalidierung erfüllen und ihnen genügen .

Ich weiß, dies ist etwas anders als das Problem in der Frage, aber es ist eine beliebte Frage, so dass ich dachte, ich würde ein bisschen mehr, um die Antwort für andere mit dem gleichen Problem wie mich hinzufügen.
Ich hoffe, das hilft anderen :)

4voto

Chtiwi Malek Punkte 10464

Ich denke, das Hinzufügen von try/catch für jede SaveChanges() Operation ist keine gute Praxis, es ist besser, dies zu zentralisieren:

Fügen Sie diese Klasse der Haupt DbContext Klasse :

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

Dies überschreibt den Kontext Ihres SaveChanges() Methode und Sie erhalten eine kommagetrennte Liste mit allen Fehlern bei der Entitätsüberprüfung.

Dies kann auch verbessert werden, um Fehler in der Produktionsumgebung zu protokollieren, anstatt nur einen Fehler zu melden.

Ich hoffe, dies ist hilfreich.

3voto

Martin_W Punkte 1350

Hier ist eine Erweiterung von Tonys Erweiterung... :-)

Für Entity Framework 4.x, wenn Sie den Namen und den Wert des Schlüsselfeldes erhalten möchten, so dass Sie wissen, welche Entitätsinstanz (DB-Datensatz) das Problem hat, können Sie das Folgende hinzufügen. Dies ermöglicht den Zugriff auf die leistungsfähigeren ObjectContext-Klassenmitglieder von Ihrem DbContext-Objekt aus.

// Get the key field name & value.
// This assumes your DbContext object is "_context", and that it is a single part key.
var e = ((IObjectContextAdapter)_context).ObjectContext.ObjectStateManager.GetObjectStateEntry(validationErrors.Entry.Entity);
string key = e.EntityKey.EntityKeyValues[0].Key;
string val = e.EntityKey.EntityKeyValues[0].Value;

3voto

Mickey Perlstein Punkte 2144

Ich mag keine Ausnahmen Ich habe die OnSaveChanges registriert und habe dies

var validationErrors = model.GetValidationErrors();

var h = validationErrors.SelectMany(x => x.ValidationErrors
                                          .Select(f => "Entity: " 
                                                      +(x.Entry.Entity) 
                                                      + " : " + f.PropertyName 
                                                      + "->" + f.ErrorMessage));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X