实体框架 DbContext 执行的日志查询
Posted
技术标签:
【中文标题】实体框架 DbContext 执行的日志查询【英文标题】:Log Queries executed by Entity Framework DbContext 【发布时间】:2014-07-11 08:53:21 【问题描述】:我在 MVC 5 项目中使用 EF 6.0 和 LINQ。我想记录实体框架 DbContext 执行的所有 SQL 查询,以用于调试/性能测量。
在 Java/Hibernate 中,可以通过设置属性 hibernate.show_sql=true
来实现等效行为。实体框架中是否可能有类似的行为?
【问题讨论】:
How do I view the SQL generated by the entity framework? 的可能重复项 【参考方案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);
【讨论】:
以上是关于实体框架 DbContext 执行的日志查询的主要内容,如果未能解决你的问题,请参考以下文章
将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表
开发中遇到的问题---使用mybatis时 有一个sql查询不到结果 日志也显示查询为o 但是从日志中取出执行的sql到数据库客户端手动执行,可以查到数据