我有一个使用实体框架的项目。而在我的DbContext上调用SaveChanges时,我得到了以下异常:

System.Data.Entity.Validation.DbEntityValidationException:验证 一个或多个实体失败。参见'EntityValidationErrors'属性 欲知详情。

这一切都很好,但我不希望每次发生此异常时都附加调试器。此外,在生产环境中,我不能轻易地附加调试器,因此我必须竭尽全力重现这些错误。

我如何才能看到隐藏在DbEntityValidationException中的细节?


当前回答

在代码中使用try块

try
{
    // Your code...
    // Could also be before try if you know the exception occurs in SaveChanges

    context.SaveChanges();
}
catch (DbEntityValidationException e)
{
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.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)
        {
            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;
}

你也可以在这里查看详细信息

http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/ 一个或多个实体验证失败。更多细节请参见'EntityValidationErrors'属性 http://blogs.infosupport.com/improving-dbentityvalidationexception/

其他回答

在代码中使用try块

try
{
    // Your code...
    // Could also be before try if you know the exception occurs in SaveChanges

    context.SaveChanges();
}
catch (DbEntityValidationException e)
{
    foreach (var eve in e.EntityValidationErrors)
    {
        Console.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)
        {
            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                ve.PropertyName, ve.ErrorMessage);
        }
    }
    throw;
}

你也可以在这里查看详细信息

http://mattrandle.me/viewing-entityvalidationerrors-in-visual-studio/ 一个或多个实体验证失败。更多细节请参见'EntityValidationErrors'属性 http://blogs.infosupport.com/improving-dbentityvalidationexception/

Actually, this is just the validation issue, EF will validate the entity properties first before making any changes to the database. So, EF will check whether the property's value is out of range, like when you designed the table. Table_Column_UserName is varchar(20). But, in EF, you entered a value that longer than 20. Or, in other cases, if the column does not allow to be a Null. So, in the validation process, you have to set a value to the not null column, no matter whether you are going to make the change on it. I personally, like the Leniel Macaferi answer. It can show you the detail of the validation issues

正如Martin所指出的,在DbEntityValidationResult中有更多信息。我发现在每条消息中同时获取POCO类名和属性名很有用,并且希望避免为此在所有[Required]标记上编写自定义ErrorMessage属性。

以下对Martin代码的调整为我解决了这些细节问题:

// Retrieve the error messages as a list of strings.
List<string> errorMessages = new List<string>();
foreach (DbEntityValidationResult validationResult in ex.EntityValidationErrors)
{
    string entityName = validationResult.Entry.Entity.GetType().Name;
    foreach (DbValidationError error in validationResult.ValidationErrors)
    {
        errorMessages.Add(entityName + "." + error.PropertyName + ": " + error.ErrorMessage);
    }
}

要查看EntityValidationErrors集合,请将以下Watch表达式添加到Watch窗口。

((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrors

我使用的是visual studio 2013

最简单的解决方案是覆盖实体类上的SaveChanges。您可以捕获DbEntityValidationException,打开实际错误并使用改进的消息创建一个新的DbEntityValidationException。

在SomethingSomething.Context.cs文件旁边创建一个partial类。 使用这篇文章底部的代码。 就是这样。您的实现将自动使用覆盖的SaveChanges,而不需要任何重构工作。

你的异常消息现在看起来像这样:

System.Data.Entity.Validation.DbEntityValidationException:验证 一个或多个实体失败。参见'EntityValidationErrors'属性 欲知详情。验证错误如下 必须是字符串或数组类型,最大长度为'12';的 LastName字段是必需的。

你可以在任何继承自DbContext的类中删除被重写的SaveChanges:

public partial class SomethingSomethingEntities
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            // Retrieve the error messages as a list of strings.
            var errorMessages = ex.EntityValidationErrors
                    .SelectMany(x => x.ValidationErrors)
                    .Select(x => x.ErrorMessage);
    
            // Join the list to a single string.
            var fullErrorMessage = string.Join("; ", errorMessages);
    
            // Combine the original exception message with the new one.
            var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
    
            // Throw a new DbEntityValidationException with the improved exception message.
            throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
        }
    }
}

DbEntityValidationException还包含导致验证错误的实体。因此,如果您需要更多的信息,您可以更改上面的代码以输出关于这些实体的信息。

参见:http://devillers.nl/improving-dbentityvalidationexception/