正在从DbValidationException获取确切的错误类型

我遇到过这样的情况,我在EF 4.1的DatabaseInitializer()中初始化我的模型,并得到了这个恼人的错误"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.",因此,我转到这个EntityValidationErrors,其中有一个字段{System.Data.Entity.Validation.DbEntityValidationResult},它没有给我任何关于它无法初始化的字段的信息。 有没有办法获得有关此错误的更多信息?

把东西清理出来:

我知道如何解决字符串长度问题。我要问的是如何获得破坏模型的确切字段名。

56498 次浏览

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.

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

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

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

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.

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

catch (DbEntityValidationException ex)
{
String.Join("\n", 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

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.