0

Why does EF error interface is so unhelpful ? How can one find the exact cause for a DbContext.SaveChanges exception, when the errors tell almost nothing about the parameters involved in the exception?

One serious shortcoming of EF in my opinion is detecting what is causing a given exception after issuing SaveChanges().

It has been long since I have been struggling with EF error interface. I once helped myself a bit by writing a method that flattens all the db context validation errors providing straightforward messages with Table, Column and error message for each error. Otherwise one has to dig deep in the error structures dbContext returns... I wonder why they did this this way!

In any case, to my problem: I perform several add operations in several entities in my dbContext, and in the end issue one single SaveChanges().

Now, I GetValidationErrors() returns 0 errors, so no validation issues. But SaveChanges throws the following exception:

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

How does DbContext points out the specific cause of the error in any way when what he passes over to you is a nested labyrinth of inner objects that looks like:

enter image description here

?!

Veverke
  • 9,208
  • 4
  • 51
  • 95

1 Answers1

0

If it's the DbEntityValidationException you can just override the SaveChanges method and grab the error and re throw it with the errors parsed out something like this:

public partial class MyEntities
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            var errorMessages = ex.EntityValidationErrors
                                  .SelectMany(x => x.ValidationErrors)
                                  .Select(x => x.ErrorMessage);
            var fullErrorMessage = string.Join("\n\r", errorMessages);

            var exceptionMessage = string.Concat(ex.Message, "The validation errors are: ", fullErrorMessage);

            throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
        } 
    }
}
ewahner
  • 1,149
  • 2
  • 11
  • 23
  • I'm not sure how is this different that what was mentioned above, [here](http://devrecipeshb.blogspot.co.il/2015/08/extension-method-to-flatten-entity.html) – Veverke Dec 03 '15 at 09:35
  • Sorry I didn't see that link. But I guess it will get you the same result. So if that solution worked for you...what's the problem? – ewahner Dec 03 '15 at 13:24
  • thank's for leaving some help, but that's not the issue :-) I ask: why is it this complicated to get useful/meaningful error messages from DbContext.SaveChanges exceptions ? The way you do it (like I did to collect all errors in a single structure (my provides a little more - adds field and table name involved in the error) - **does not answer** at all the problem - because one can get a DbContext.SaveChanges exception without having any errors whatsoever in EntityValidations (which makes sense, because these only provide validation errors. An exception is a runtime error, something different) – Veverke Dec 03 '15 at 13:41
  • Well my guess would be that these are not true exceptions. They are entity issues. Meaning that a constraint could be put on a table to only allow values that begin with a letter 'a'. Is that an error? So they needed a separate place to create this collection of issues that could arise from updating a table. So you have exceptions that could be due to communication or clr issues and then you can have database issues. – ewahner Dec 03 '15 at 13:57
  • What are you calling *not true exceptions* ? The ones from DbContext.SaveChanges ? Why, these are the only exceptions here :-) Whatever EntityValidationErrors collect, they are validation errors and not exceptions (these would go more in line with what you suggest, these are not real exceptions, they are constraint enforcement failures, and alike) – Veverke Dec 03 '15 at 14:15
  • In any case, I hope you understand what my problem is and why what you posted does not help - because what you give deals only with validation problems, I want a way to efficiently extract meaningful information from DbContext.SaveChanges() exceptions, which is really not easy - sometimes I am doubtful if possible at all. – Veverke Dec 03 '15 at 14:32