c# español registro - La validación falló para una o más entidades al guardar los cambios en la base de datos de SQL Server utilizando Entity Framework




8 Answers

Puede extraer toda la información de la DbEntityValidationException con el siguiente código (debe agregar los espacios de nombres: System.Data.Entity.Validation y System.Diagnostics a su lista de using ):

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

Quiero guardar mi Editar en la base de datos y estoy usando Entity FrameWork Code-First en ASP.NET MVC 3 / C # pero estoy recibiendo errores. En mi clase de evento, tengo tipos de datos DateTime y TimeSpan pero en mi base de datos, tengo fecha y hora respectivamente. Podría ser ésta la razón? ¿Cómo puedo convertir al tipo de datos apropiado en el código antes de guardar los cambios en la base de datos?

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

Método en el controlador >>>> Problema en 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);
    }
}

con

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

Base de datos SQL Server 2008 R2 / T-SQL

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

Formulario HTTP

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  

Error del servidor en la aplicación '/'.

La validación falló para una o más entidades. Vea la propiedad 'EntityValidationErrors' para más detalles.

Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.Data.Entity.Validation.DbEntityValidationException: La validación falló para una o más entidades. Vea la propiedad 'EntityValidationErrors' para más detalles.

Error de fuente:

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

Archivo de origen: C: \ sep \ MvcEventCalendar \ MvcEventCalendar \ Controllers \ EventManagerController.cs Línea: 77

Traza de la pila:

[DbEntityValidationException: la validación falló para una o más entidades. Vea la propiedad 'EntityValidationErrors' para más detalles.]




En el caso de que tenga clases con los mismos nombres de propiedades, aquí hay una pequeña extensión de la respuesta de Praveen:

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



Esta implementación envuelve la excepción de excepción a excepción con texto detallado. Maneja DbEntityValidationException , DbUpdateException , errores de rango de datetime2 (MS SQL) e incluye la clave de la entidad no válida en el mensaje (útil cuando se guardan muchas entidades en una llamada de SaveChanges ).

Primero, anule SaveChanges en la clase DbContext:

public class AppDbContext : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }   

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        try
        {
            return await base.SaveChangesAsync(cancellationToken);
        }
        catch (DbEntityValidationException dbEntityValidationException)
        {
            throw ExceptionHelper.CreateFromEntityValidation(dbEntityValidationException);
        }
        catch (DbUpdateException dbUpdateException)
        {
            throw ExceptionHelper.CreateFromDbUpdateException(dbUpdateException);
        }
    }

Clase ExceptionHelper:

public class ExceptionHelper
{
    public static Exception CreateFromEntityValidation(DbEntityValidationException ex)
    {
        return new Exception(GetDbEntityValidationMessage(ex), ex);
    }

    public static string GetDbEntityValidationMessage(DbEntityValidationException ex)
    {
        // Retrieve the error messages as a list of strings.
        var errorMessages = ex.EntityValidationErrors
            .SelectMany(x => x.ValidationErrors)
            .Select(x => x.ErrorMessage);

        // Join the list to a single string.
        var fullErrorMessage = string.Join("; ", errorMessages);

        // Combine the original exception message with the new one.
        var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
        return exceptionMessage;
    }

    public static IEnumerable<Exception> GetInners(Exception ex)
    {
        for (Exception e = ex; e != null; e = e.InnerException)
            yield return e;
    }

    public static Exception CreateFromDbUpdateException(DbUpdateException dbUpdateException)
    {
        var inner = GetInners(dbUpdateException).Last();
        string message = "";
        int i = 1;
        foreach (var entry in dbUpdateException.Entries)
        {
            var entry1 = entry;
            var obj = entry1.CurrentValues.ToObject();
            var type = obj.GetType();
            var propertyNames = entry1.CurrentValues.PropertyNames.Where(x => inner.Message.Contains(x)).ToList();
            // check MS SQL datetime2 error
            if (inner.Message.Contains("datetime2"))
            {
                var propertyNames2 = from x in type.GetProperties()
                                        where x.PropertyType == typeof(DateTime) ||
                                            x.PropertyType == typeof(DateTime?)
                                        select x.Name;
                propertyNames.AddRange(propertyNames2);
            }

            message += "Entry " + i++ + " " + type.Name + ": " + string.Join("; ", propertyNames.Select(x =>
                string.Format("'{0}' = '{1}'", x, entry1.CurrentValues[x])));
        }
        return new Exception(message, dbUpdateException);
    }
}



Recibí este error hoy y no pude resolverlo por un tiempo, pero me di cuenta de que era después de agregar algunos RequireAttribute s a mis modelos y que algunos datos de semilla de desarrollo no estaban RequireAttribute todos los campos requeridos.
Entonces, solo tenga en cuenta que si obtiene este error al actualizar la base de datos a través de algún tipo de estrategia de inicio como DropCreateDatabaseIfModelChanges , debe asegurarse de que sus datos iniciales cumplan y satisfagan los atributos de validación de datos del modelo .

Sé que esto es un poco diferente al problema en la pregunta, pero es una pregunta popular, así que pensé que agregaría un poco más a la respuesta para otros que tienen el mismo problema que yo.
Espero que esto ayude a otros :)




Aquí hay una extensión de la extensión de Tony ... :-)

Para Entity Framework 4.x, si desea obtener el nombre y el valor del campo clave para saber qué instancia de entidad (registro DB) tiene el problema, puede agregar lo siguiente. Esto proporciona acceso a los miembros de la clase ObjectContext más poderosos desde su objeto DbContext.

// 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;



Este error también ocurre cuando intenta guardar una entidad que tiene errores de validación. Una buena manera de hacer esto es olvidarse de revisar ModelState.IsValid antes de guardar en su base de datos.




Esto podría deberse a la cantidad máxima de caracteres permitidos para una columna específica, como en sql, un campo podría tener el tipo de datos siguiente nvarchar(5) pero la cantidad de caracteres ingresados ​​por el usuario es mayor que la especificada, por lo que surge el error.




Gracias por sus respuestas, me ayudó mucho. Al codificar en Vb.Net, este código Bolt para Vb.Net

Try
   Return MyBase.SaveChanges()
Catch dbEx As Validation.DbEntityValidationException
   For Each [error] In From validationErrors In dbEx.EntityValidationErrors
                       From validationError In validationErrors.ValidationErrors
                       Select New With { .PropertyName = validationError.PropertyName,
                                         .ErrorMessage = validationError.ErrorMessage,
                                         .ClassFullName = validationErrors.Entry.Entity
                                                                    .GetType().FullName}

        Diagnostics.Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                                           [error].ClassFullName,
                                           [error].PropertyName,
                                           [error].ErrorMessage)
   Next
   Throw
End Try



Related