English 中文(简体)
Getting exact error type in from DbValidationException
原标题:

I have the situation where I m initializing my model in DatabaseInitializer() for EF 4.1 and get this annoying error "Validation failed for one or more entities. See EntityValidationErrors property for more details." So, I go to this EntityValidationErrors and there is a field {System.Data.Entity.Validation.DbEntityValidationResult} which gives me no information at all about what field it was unable to initialize. Is there a way to get more info about this error?

To clear things out:

I know how to fix the string length problem. What I m asking is how do I get the exact field name that is breaking the model.

最佳回答

While you are in debug mode within the catch {...} block open up the "QuickWatch" window (ctrl+alt+q) and paste in there:

((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors

This will allow you to drill down into the ValidationErrors tree. It s the easiest way I ve found to get instant insight into these errors.

For Visual 2012+ users who care only about the first error and might not have a catch block, you can even do:

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage
问题回答

You could try this in a try/catch block?

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

The best solution in my opinion, is to handle this kind of errors in a centralized way.

just add this method to the main DbContext class :

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

This will overwrite your context s SaveChanges() method and you ll get a comma separated list containing all the entity validation errors.

hope this is helpful.

Well, I had same problem. My model worked good in EF CTP5 but failed to build in 4.1 with the same error ""Validation failed for one or more entities" when I tried to initalize it. I figured out that I had property:

public string Comment {get; set;}

Then in seed method in overrided initializer, I had quite a bit long (about 600 letters) comment.

I think the point is: in EF 4.1 you have to set data annotations explicitly in some cases. For me, setting:

[StringLength(4000)] 
public string Comment {get; set;}

helped. It s weird since CTP5 had no problems with that.

I know it s an old question but here s my answer:

catch (DbEntityValidationException ex)
   {
    String.Join("
", ex.EntityValidationErrors
          .SelectMany(x => x.ValidationErrors)
          .Select(x => x.ErrorMessage)
          .ToArray());
   }

and if you use code first, you can also globalize your error messages using multiple resource files

For instance I have these two seperate resource file, one for error and one for property name and I use them as following: enter image description here enter image description here

public class Person 
    {
        [Required(ErrorMessageResourceName = "required",ErrorMessageResourceType =typeof(ErrorMessages))]
        [MaxLength(100,ErrorMessageResourceName = "maxLength", ErrorMessageResourceType = typeof(ErrorMessages))]
        [Display(Name = "FirstName",ResourceType = typeof(Properties))]
        public string FirstName { get; set; }
         }

As you can see I have completely translated my error messages including the properties names, so I could then use them in the user later for instance:

enter image description here

I found it useful to create a SaveChanges wrapper which makes the EntityValidationErrors more readable:

Public Sub SaveChanges(entities As Entities)

    Try
        entities.SaveChanges()

    Catch ex As DbEntityValidationException

        Dim msg As New StringBuilder
        msg.AppendLine(ex.Message)

        For Each vr As DbEntityValidationResult In ex.EntityValidationErrors
            For Each ve As DbValidationError In vr.ValidationErrors
                msg.AppendLine(String.Format("{0}: {1}", ve.PropertyName, ve.ErrorMessage))
            Next
        Next

        Throw New DbEntityValidationException(msg.ToString, ex.EntityValidationErrors, ex)

    End Try

End Sub

and then changed entities.SaveChanges() to SaveChanges(entities) in my entire project

Verify that all of the fields you are trying to save that are not nullable have values. It may actually take less time than figuring out cryptic error messages.

This error reason: For example, you have a field that is Surname in your Database. The field type is nvarchar(50) but you try to enter 55 length. So, you can get this error.

I got like this error when the length is problem. But it can be another reasons.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签