Tom*_*gan 4 c# entity-framework .net-core
在 .Net Core 2.2 中使用实体框架,我想将 EF 生成的所有 SQL 语句记录到 Visual Studio 中的调试输出窗口。
在 .Net Framework 中,我只需将此行添加到 DbContext 构造函数中:
Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Run Code Online (Sandbox Code Playgroud)
在 EF 中,我正在尝试以下操作。它编译,并且 OnConfiguring 方法确实被调用,但没有数据库调用记录到我的调试输出窗口。我错过了什么?
public class MyContext : DbContext
{
private ILoggerFactory GetLoggerFactory()
{
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder
.AddDebug()
.AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Debug));
return serviceCollection.BuildServiceProvider()
.GetService<ILoggerFactory>();
}
public MyContext(DbContextOptions<MembershipContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(GetLoggerFactory());
}
}
Run Code Online (Sandbox Code Playgroud)
我的 appsettings.json 包含这个:
"Logging": {
"LogLevel": {
"Default": "Debug"
}
Run Code Online (Sandbox Code Playgroud)
},
我的 Startup.cs 在 ConfigureServices 方法中包含这一行:
services.AddDbContext<MyContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyConnectionSTring")));
Run Code Online (Sandbox Code Playgroud)
Startup.cs 也包含以下每个答案,但它不会导致 EF SQL 打印到输出窗口:
public ILogger<Startup> Logger { get; set; }
public Startup(IConfiguration configuration, ILogger<Startup> logger)
{
Configuration = configuration;
Logger = logger;
//the following line gets printed to my debug output window:
logger.LogDebug("this is a debug message");
}
Run Code Online (Sandbox Code Playgroud)
我无法在我的 EFCore 3 应用程序中使用 .AddDebug()。我在我的项目中添加了 nuget 包 Microsoft.Extensions.Logging.Debug 并且能够使用它。我现在在输出窗口中看到生成的 SQL 命令(显示来自调试的输出)。
在上下文中创建一个字段:
public static readonly ILoggerFactory _loggerFactory
= LoggerFactory.Create(builder => builder.AddDebug().AddFilter((category, level) => level == LogLevel.Information && !category.EndsWith("Connection")));
Run Code Online (Sandbox Code Playgroud)
并将该字段添加到您的 optionsBuilder:
optionsBuilder.UseLoggerFactory(_loggerFactory);
Run Code Online (Sandbox Code Playgroud)
感谢您的评论和回答。这里的问题出在我的耳朵之间。我最初在问题中发布的代码有效;它将原始 SQL 记录到实体 SQL 查询的调试输出窗口。
事实上,如果应用程序使用 asp.net core(这个应用程序就是这样,它是一个 Web api 应用程序),则需要的东西会少很多。默认情况下,Visual Studio 2017 会在 Program.cs 中插入以下代码作为项目模板的一部分:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
Run Code Online (Sandbox Code Playgroud)
对 CreateDefaultBuilder 的调用添加了 3 种类型的日志记录——控制台、调试、EventSource——并且还从 appsettings.json 中获取“日志记录”部分。我原来的问题中的“LoggerFactory”内容是多余的并且不需要。
我正在测试并失败的代码在使用数据库上下文时正在使用 System.Data.Common.DbCommand 执行存储过程,该过程不会将信息传递给连接到 DbContext 的记录器。我需要手动记录 System.Data.Common.DbCommand sql 语句(这在 .Net Framework 中也是需要的,但自从我接触这个以来已经很多年了,我已经忘记了)。
当我在 DbContext 中创建 DbSet 并使用 Entity SQL 对其进行选择时,例如:
var log = _myContext.Log.FirstOrDefault(o => o.Id > 0);
Run Code Online (Sandbox Code Playgroud)
这成功地将原始 SQL 记录到我的调试输出窗口,例如:
Microsoft.EntityFrameworkCore.Database.Command:Information:
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [o].[Id], [o].[Browser], [o].[Client], [o].[Date], [o].[Exception],
[o].[Host], [o].[Level], [o].[Logger], [o].[Message], [o].[StackTrace], [o].[Thread],
[o].[User]
FROM [Log] AS [o]
WHERE [o].[Id] > 0
Run Code Online (Sandbox Code Playgroud)