.net 从 DbValidationException 获取准确的错误类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5345890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting exact error type in from DbValidationException
提问by Naz
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?
我有这样的情况,我在 DatabaseInitializer() 中为 EF 4.1 初始化我的模型并得到这个烦人的错误"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."所以,我去这个 EntityValidationErrors 并且有一个字段{System.Data.Entity.Validation.DbEntityValidationResult}没有给我任何关于它无法初始化的字段的信息. 有没有办法获得有关此错误的更多信息?
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.
我知道如何解决字符串长度问题。我要问的是如何获得破坏模型的确切字段名称。
回答by GONeale
While you are in debug mode within the catch {...}block open up the "QuickWatch" window (ctrl+alt+q) and paste in there:
当您在catch {...}块中处于调试模式时,打开“QuickWatch”窗口(ctrl+ alt+ q)并粘贴到那里:
((System.Data.Entity.Validation.DbEntityValidationException)ex).EntityValidationErrors
This will allow you to drill down into the ValidationErrorstree. It's the easiest way I've found to get instant insight into these errors.
这将允许您深入到ValidationErrors树中。这是我发现的立即洞察这些错误的最简单方法。
For Visual 2012+ users who care only about the first error and might not have a catchblock, you can even do:
对于只关心第一个错误并且可能没有catch块的Visual 2012+ 用户,您甚至可以这样做:
((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors.First().ValidationErrors.First().ErrorMessage
回答by Trent Scholl
You could try this in a try/catch block?
你可以在 try/catch 块中试试这个吗?
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);
}
}
}
回答by Chtiwi Malek
The best solution in my opinion, is to handle this kind of errors in a centralized way.
在我看来,最好的解决方案是以集中方式处理此类错误。
just add this method to the main DbContextclass :
只需将此方法添加到主DbContext类:
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.
这将覆盖您的上下文SaveChanges()方法,您将获得一个包含所有实体验证错误的逗号分隔列表。
hope this is helpful.
希望这是有帮助的。
回答by Wojciech Kotlinski
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:
嗯,我有同样的问题。我的模型在 EF CTP5 中运行良好,但无法在 4.1 中构建,并在我尝试初始化它时出现相同的错误“一个或多个实体的验证失败”。我发现我有属性:
public string Comment {get; set;}
Then in seed method in overrided initializer, I had quite a bit long (about 600 letters) comment.
然后在覆盖初始值设定项中的种子方法中,我有相当长的(大约 600 个字母)注释。
I think the point is: in EF 4.1 you haveto set data annotations explicitly in some cases. For me, setting:
我认为重点是:在 EF 4.1 中,您必须在某些情况下明确设置数据注释。对我来说,设置:
[StringLength(4000)]
public string Comment {get; set;}
helped. It's weird since CTP5 had no problems with that.
有帮助。这很奇怪,因为 CTP5 对此没有任何问题。
回答by smirkingman
I found it useful to create a SaveChanges wrapper which makes the EntityValidationErrors more readable:
我发现创建一个 SaveChanges 包装器很有用,这使得 EntityValidationErrors 更具可读性:
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
然后在我的整个项目中将 'entities.SaveChanges()' 更改为 'SaveChanges(entities)'
回答by NikiUsefi
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:


例如,我有这两个单独的资源文件,一个用于错误,一个用于属性名称,我使用它们如下:


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:
正如你所看到的,我已经完全翻译了我的错误消息,包括属性名称,所以我可以稍后在用户中使用它们,例如:

