【问题标题】:Entity Framework - printing EntityValidationErrors to log实体框架 - 打印 EntityValidationErrors 以记录
【发布时间】:2012-12-11 17:36:14
【问题描述】:

打印日志时出现以下错误

Message: Validation failed for one or more entities. See 'EntityValidationErrors'  
property for more details.; Stack Trace:    at 
System.Data.Entity.Internal.InternalContext.SaveChanges()

EntityValidationErrors 对象保存不同节点中的完整详细错误。 打印它的最佳方法是什么?

【问题讨论】:

    标签: c# entity-framework logging entity-framework-4


    【解决方案1】:

    更简洁的语法:

    catch (System.Data.Entity.Validation.DbEntityValidationException ex)
    {
         Logger.WriteError("{0}{1}Validation errors:{1}{2}", ex, Environment.NewLine, ex.EntityValidationErrors.Select(e => string.Join(Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))));
         throw;
    }
    

    【讨论】:

    • 完美,如果您刚刚遇到异常并想在即时窗口中看到它,您可以使用“$exception”这样:$exception.EntityValidationErrors.Select(e => string.Join (Environment.NewLine, e.ValidationErrors.Select(v => string.Format("{0} - {1}", v.PropertyName, v.ErrorMessage)))))
    【解决方案2】:

    这里有一些扩展方法:

    /// <summary>
    ///     A DbEntityValidationException extension method that formates validation errors to string.
    /// </summary>
    public static string DbEntityValidationExceptionToString(this DbEntityValidationException e)
    {
        var validationErrors = e.DbEntityValidationResultToString();
        var exceptionMessage = string.Format("{0}{1}Validation errors:{1}{2}", e, Environment.NewLine, validationErrors);
        return exceptionMessage;
    }
    
    /// <summary>
    ///     A DbEntityValidationException extension method that aggregate database entity validation results to string.
    /// </summary>
    public static string DbEntityValidationResultToString(this DbEntityValidationException e)
    {
        return e.EntityValidationErrors
                .Select(dbEntityValidationResult => dbEntityValidationResult.DbValidationErrorsToString(dbEntityValidationResult.ValidationErrors))
                .Aggregate(string.Empty, (current, next) => string.Format("{0}{1}{2}", current, Environment.NewLine, next));
    }
    
    /// <summary>
    ///     A DbEntityValidationResult extension method that to strings database validation errors.
    /// </summary>
    public static string DbValidationErrorsToString(this DbEntityValidationResult dbEntityValidationResult, IEnumerable<DbValidationError> dbValidationErrors)
    {
        var entityName = string.Format("[{0}]", dbEntityValidationResult.Entry.Entity.GetType().Name);
        const string indentation = "\t - ";
        var aggregatedValidationErrorMessages = dbValidationErrors.Select(error => string.Format("[{0} - {1}]", error.PropertyName, error.ErrorMessage))
                                               .Aggregate(string.Empty, (current, validationErrorMessage) => current + (Environment.NewLine + indentation + validationErrorMessage));
        return string.Format("{0}{1}", entityName, aggregatedValidationErrorMessages);
    }
    

    用例 1:

    catch(DbEntityValidationException e) {
        Logger.WriteError(e.DbEntityValidationExceptionToString());
        throw;      
    }
    

    应该输出:

    StackTrace
    Validation errores:
    [EntityName]
        - [Property - ErrorMessage]
        - [Property - ErrorMessage]
    [EntityName2]
        - [Property - ErrorMessage]
        - [Property - ErrorMessage]
    

    用例 2:

    catch(DbEntityValidationException e) {
        Logger.WriteError(e.DbEntityValidationResultToString());
        throw;      
    }
    

    应该输出:

    [EntityName]
        - [Property - ErrorMessage]
        - [Property - ErrorMessage]
    [EntityName2]
        - [Property - ErrorMessage]
        - [Property - ErrorMessage]
    

    【讨论】:

    • Logger 驻留在哪个命名空间中?我无法在内置记录器类中找到 WriteError 方法
    • @shivisuper 这只是一个示例,而不是扩展代码的一部分,它只是向您展示了如何使用扩展代码...将Logger.WriteErrorConsole.WriteLine 切换为控制台应用程序等等……
    • @furier 哦,我明白了,我的错
    【解决方案3】:

    你可以试试这样的

       foreach (var failure in ex.EntityValidationErrors)
        {
           string validationErrors="";
    
            foreach (var error in failure.ValidationErrors)
            {
               validationErrors+=error.PropertyName+"  "+error.ErrorMessage;
            }
        }
    

    【讨论】:

    • 将上面的代码放入try catch - try {...} catch(Exception ex) {...}
    • 反对不使用 StringBuilder。循环中的字符串连接是危险的做法。
    • 危险吗?最坏的情况是没有性能......并且因为它处于尝试捕获(昂贵的操作)中,所以没关系。
    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2021-09-21
    • 1970-01-01
    • 2013-06-30
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多