【问题标题】:Log Queries executed by Entity Framework DbContext实体框架 DbContext 执行的日志查询
【发布时间】:2014-07-11 08:53:21
【问题描述】:

我在 MVC 5 项目中使用 EF 6.0 和 LINQ。我想记录实体框架 DbContext 执行的所有 SQL 查询,以用于调试/性能测量。

在 Java/Hibernate 中,可以通过设置属性 hibernate.show_sql=true 来实现等效行为。实体框架中是否可能有类似的行为?

【问题讨论】:

标签: c# linq entity-framework asp.net-mvc-5 entity-framework-6


【解决方案1】:

Logging and Intercepting Database Operations MSDN 上的文章正是您想要的。

DbContext.Database.Log 属性可以设置为任何采用字符串的方法的委托。最常见的是,通过将其设置为该 TextWriter 的“Write”方法,它与任何 TextWriter 一起使用。当前上下文生成的所有 SQL 都将记录到该编写器。例如,以下代码会将 SQL 记录到控制台:

using (var context = new BlogContext())
{
    context.Database.Log = Console.Write;

    // Your code here...
}

【讨论】:

  • 仅供参考:如果您使用context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);,那么它只会在调试模式下登录。在释放模式下,对 System.Diagnostics.Debug 的调用将被忽略。
  • 或者你可以将这行代码包装到用[Conditional("Debug")]属性修饰的方法中
  • @Andrew,你能告诉我这个 Database.log 操作是在哪里调用的吗?
  • 这似乎可行,但生成的 sql 查询是参数化的。在调试模式下,我将如何打印参数化值?
【解决方案2】:

您可以使用此行将 SQL 查询仅记录到 Visual Studio“输出”窗口,而不是控制台窗口,同样仅在调试模式下。

public class YourContext : DbContext
{   
    public YourContext()
    {
        Database.Log = sql => Debug.Write(sql);
    }
}

【讨论】:

    【解决方案3】:

    如果您有一个带有记录器的 .NET Core 设置,那么 EF 会将其查询记录到您想要的任何输出:调试输出窗口、控制台、文件等。

    您只需要在 appsettings 中配置“信息”日志级别。例如,这会将 EF 记录到调试输出窗口:

    "Logging": {
      "PathFormat": "Logs/log-{Date}.txt",
      "IncludeScopes": false,
      "Debug": {
        "LogLevel": {
          "Default": "Information",
          "System": "Information",
          "Microsoft": "Information"
        }
      },
      "Console": {
        "LogLevel": {
          "Default": "Information",
          "System": "Warning",
          "Microsoft": "Warning"
        }
      },
      "File": {
        "LogLevel": {
          "Default": "Information",
          "System": "Warning",
          "Microsoft": "Warning"
        }
      },
      "LogLevel": {
        "Default": "Information",
        "System": "Warning",
        "Microsoft": "Warning"
      }
    }
    

    【讨论】:

      【解决方案4】:

      EF Core 日志记录自动与 .NET Core 的日志记录机制集成。示例如何使用它登录到控制台:

      public class SchoolContext : DbContext
      {
          //static LoggerFactory object
          public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
                    new ConsoleLoggerProvider((_, __) => true, true)
              });
      
          //or
          // public static readonly ILoggerFactory loggerFactory  = new LoggerFactory().AddConsole((_,___) => true);
      
          public SchoolContext():base()
          {
      
          }
      
          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          {
              optionsBuilder.UseLoggerFactory(loggerFactory)  //tie-up DbContext with LoggerFactory object
                  .EnableSensitiveDataLogging()  
                  .UseSqlServer(@"Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;");
          }
      
          public DbSet<Student> Students { get; set; }
      }
      

      如果您想登录到输出窗口,请改用:

      public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
            new DebugLoggerProvider()
      });
      

      https://www.entityframeworktutorial.net/efcore/logging-in-entityframework-core.aspx

      【讨论】:

        【解决方案5】:

        如果有人使用 EF6.1+,有一个简单的方法。查看以下链接了解更多详情。

        https://docs.microsoft.com/en-us/ef/ef6/fundamentals/configuring/config-file#interceptors-ef61-onwards

        示例代码

        <interceptors>
          <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
            <parameters>
              <parameter value="C:\Stuff\LogOutput.txt"/>
              <parameter value="true" type="System.Boolean"/>
            </parameters>
          </interceptor>
        </interceptors>
        

        【讨论】:

          【解决方案6】:

          实体框架核心 3

          来自this article

          创建工厂并设置过滤器。

          var loggerFactory = LoggerFactory.Create(builder =>
          {
              builder
              .AddConsole((options) => { })
              .AddFilter((category, level) =>
                  category == DbLoggerCategory.Database.Command.Name
                  && level == LogLevel.Information);
          });
          

          在 OnConfiguring 方法中告诉 DbContext 使用工厂:

          optionsBuilder.UseLoggerFactory(_loggerFactory);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-14
            • 1970-01-01
            • 2013-05-03
            • 1970-01-01
            相关资源
            最近更新 更多