【问题标题】:Entity Framework Logging not working on exception实体框架日志记录不适用于异常
【发布时间】:2018-08-09 18:15:07
【问题描述】:

我已根据here 的指南实施了实体框架日志记录。但是,它只在没有异常的情况下记录!!!我通过分配超过允许的字符创建了一个system.FormatException: Input string was not in a correct format.。我的代码是:

Databasecontext context=new DatabaseContext();
TableCity tbCity;
var logger = new MyLogger();           
context.Database.Log = l => logger.Log("Table-tableNews", l);
tbCity.City ="sdkjfaksdjfsdjfjasdfjsdjfjdfjdjfjasdfjlasdjfljdfjdadsfdf";//varchar(25) in dbase
.......... //code removed for clarity
context.TableName.Add(tbCity);
try{
   context.SaveChanges();
 }
 catch(Exception ex)
 {}

我的日志方法

 public void Log(string component, string messages)
 {
    //contents here, which works as desired
 }

我需要以不同的方式实现来记录异常吗?

【问题讨论】:

  • 是的,记录生成的 SQL 不同于记录异常。如果发生异常,则不会生成 SQL。对于例外情况,请使用ELMAH 之类的工具。
  • 谢谢史蒂夫。我已经在另一个项目中使用了 ELMAH。不过,我想尝试一些不同的东西,我喜欢 ELMAH。

标签: c# asp.net-mvc entity-framework logging


【解决方案1】:

如果您在提到的链接上有scrolled down,您就会遇到IDbCommandInterceptor 界面。它的功能更加丰富,它可以判断查询是成功执行还是失败。

一个示例实现可能是:

public class LogDbCommandInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        interceptionContext.SetUserState("start", DateTime.Now);
    }

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
        Console.WriteLine($"parameters: {FormatParams(command.Parameters)}, exception: {interceptionContext.Exception?.Message}");
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        interceptionContext.SetUserState("start", DateTime.Now);
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        interceptionContext.SetUserState("start", DateTime.Now);
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        Console.WriteLine($"sql command: {command.CommandText}, hasFailed: {HasFailed(interceptionContext)}, duration: {CalculateDuration(interceptionContext)}");
    }

    private static double CalculateDuration<T>(DbCommandInterceptionContext<T> context)
    {
        return (DateTime.Now - (DateTime)context.FindUserState("start")).TotalMilliseconds;
    }

    private static bool HasFailed<T>(DbCommandInterceptionContext<T> context)
    {
        return context.OriginalException != null || (context.IsAsync && context.TaskStatus != TaskStatus.RanToCompletion);
    }

    private static string FormatParams(ICollection dbParameterCollection)
    {
        if (dbParameterCollection.Count == 0)
            return string.Empty;

        var parameterDescriptor = new StringBuilder();

        foreach (SqlParameter parameter in dbParameterCollection)
        {
            parameterDescriptor.AppendFormat("{0} {1}: {2}, ", parameter.DbType, parameter.ParameterName, parameter.Value);
        }

        return parameterDescriptor.ToString().TrimEnd(' ', ',');
    }
}

Console.WriteLine 当然可以用您自己的记录器替换。

如您所见,您可以使用OriginalException 属性读取异常。其他感兴趣的属性被监听here.

还可以在here 找到注册实施的简短指南:

注册拦截器 一旦创建了实现一个或多个拦截接口的类,就可以使用 DbInterception 类向 EF 注册它

拦截器也可以使用基于 DbConfiguration 代码的配置在应用域级别注册

您还可以使用 app.config 文件配置拦截器

【讨论】:

  • 感谢您的建议,我会在实施后回来。
  • @curious.netter 您好,它对您有用还是遇到了其他问题?
  • 我一直在忙其他项目,会尽快检查并回来。
  • 它可以工作,但没有 SetUserState 方法,但有一个名为 UserState 的属性。这个概念是一样的,我只是稍微调整了一下,让它起作用。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-02-06
  • 2019-02-21
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-12
相关资源
最近更新 更多