When calling DbContext.SaveChanges
, I get a DbUpdateException:
An unhandled exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll. Additional information: An error occurred while updating the entries. See the inner exception for details.
Unfortunately, there is no inner exception (at least, not as far as I can see). Is there any way to see exactly why SaveChanges
threw an exception? At the very least, it would be helpful to see what table SaveChanges tried to update with when the error occured.
Exception thrown by DbContext when the saving of changes to the database fails.
This is my override of SaveChanges. It gives me a useful place to put breakpoints:
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; } }
Reference:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
Here's my override of SaveChanges, showing the additional code to deal with the DbUpdateException (as per the question).
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); }
I've not made the logging code very specific, but it improves on the standard error message of something like:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
This way, at least I can see which entity has the problem, and that's normally enough to work it out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With