Encontrar el motivo de DBUpdateException

Cuando llamo a DbContext.SaveChanges , obtengo una DbUpdateException:

Se produjo una excepción no controlada del tipo ‘System.Data.Entity.Infrastructure.DbUpdateException’ en EntityFramework.dll. Información adicional: se produjo un error al actualizar las entradas. Ver la excepción interna para más detalles.

Desafortunadamente, no hay una excepción interna (al menos, no tan lejos como puedo ver). ¿Hay alguna manera de ver exactamente por qué SaveChanges lanzó una excepción? Por lo menos, sería útil ver con qué tabla SaveChanges intentó actualizar cuando se produjo el error.

Cuando parece que la verdadera excepción se pierde en alguna parte, su mejor opción es romper con cada excepción. Independientemente de si está atrapado o ingerido en algún lugar, dentro o fuera de su scope, el depurador se romperá y le permitirá ver lo que está sucediendo.

Vea este enlace de MSDN para más información:

Cómo: Romper cuando se lanza una excepción

Esta es mi anulación de SaveChanges. Me da un lugar útil para poner puntos de corte:

  public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException e) { foreach (var eve in e.EntityValidationErrors) { Debug.WriteLine(@"Entity of type ""{0}"" in state ""{1}"" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State); foreach (var ve in eve.ValidationErrors) { Debug.WriteLine(@"- Property: ""{0}"", Error: ""{1}""", ve.PropertyName, ve.ErrorMessage); } } throw; } catch(DbUpdateException e) { //Add your code to inspect the inner exception and/or //e.Entries here. //Or just use the debugger. //Added this catch (after the comments below) to make it more obvious //how this code might help this specific problem } catch (Exception e) { Debug.WriteLine(e.Message); throw; } } 

Referencia:

La validación falló para una o más entidades. Consulte la propiedad ‘EntityValidationErrors’ para más detalles

Aquí está mi anulación de SaveChanges, que muestra el código adicional para tratar con la DbUpdateException (según la pregunta).

  public override int SaveChanges() { try { return base.SaveChanges(); } catch (DbEntityValidationException vex) { var exception = HandleDbEntityValidationException(vex); throw exception; } catch(DbUpdateException dbu) { var exception = HandleDbUpdateException(dbu); throw exception; } } private Exception HandleDbUpdateException(DbUpdateException dbu) { var builder = new StringBuilder("A DbUpdateException was caught while saving changes. "); try { foreach (var result in dbu.Entries) { builder.AppendFormat("Type: {0} was part of the problem. ", result.Entity.GetType().Name); } } catch (Exception e) { builder.Append("Error parsing DbUpdateException: " + e.ToString()); } string message = builder.ToString(); return new Exception(message, dbu); } 

No he hecho que el código de registro sea muy específico, pero mejora el mensaje de error estándar de algo así como:

 The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. 

De esta forma, al menos puedo ver qué entidad tiene el problema, y ​​eso es normalmente suficiente para resolverlo.

En base a la respuesta de Colin, se puede proporcionar información completamente detallada sobre la falla de persistencia EF de esta manera:

 public bool SaveChangesEx() { try { SaveChanges(); return true; } catch (DbEntityValidationException exc) { // just to ease debugging foreach (var error in exc.EntityValidationErrors) { foreach (var errorMsg in error.ValidationErrors) { // logging service based on NLog Logger.Log(LogLevel.Error, $"Error trying to save EF changes - {errorMsg.ErrorMessage}"); } } throw; } catch (DbUpdateException e) { var sb = new StringBuilder(); sb.AppendLine($"DbUpdateException error details - {e?.InnerException?.InnerException?.Message}"); foreach (var eve in e.Entries) { sb.AppendLine($"Entity of type {eve.Entity.GetType().Name} in state {eve.State} could not be updated"); } Logger.Log(LogLevel.Error, e, sb.ToString()); throw; } } 

Además de los errores de validación, la excepción de actualización arrojará tanto el error general como la información de contexto.

Nota: C # 6.0 es necesario para que este código funcione, ya que usa propagación nula e interpolación de cadenas.

Estaba teniendo el mismo error “La conversión de un tipo de datos datetime2 a un tipo de datos datetime resultó en un valor fuera de rango. \ R \ nLa statement ha finalizado”.

Puse el campo de valor de fecha y hora como este Datetime.Now

 var person = new Person { FirstName = "Sebastian", LastName = "Back", **BirthDate = DateTime.Now,** IsActive = true, }; 

Tengo el mismo error y lo soluciono así;

Tengo un campo cuyo tipo de datos es datetime y sé que lo estoy configurando sin la propiedad datetime asignada. Así que lo cambio a ” Datetime.Now ” luego veo que el problema fue resuelto y se ha guardado con éxito

En mi caso, yo estaba usando Stored Procedure para agregar una entidad a DB. Mi SP está dando el error de tiempo de ejecución debido a que estaba obteniendo este error en C #. Corregí el SP y el EF funcionó a la perfección. Por lo tanto, si está utilizando SP para agregar, editar, eliminar o actualizar en EF, compruebe si el sp correspondiente funciona correctamente.