在.Net Core 2.2中使用实体框架,我想将EF生成的所有SQL语句记录到Visual Studio的“调试输出”窗口中。
在.Net Framework中,我只需要将此行添加到DbContext构造函数中即可:
Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
在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());
}
}
我的appsettings.json包含以下内容:
"Logging": {
"LogLevel": {
"Default": "Debug"
}
},
我的Startup.cs在ConfigureServices方法中包含以下行:
services.AddDbContext<MyContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyConnectionSTring")));
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");
}
答案 0 :(得分:4)
我无法在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")));
并将该字段添加到您的optionsBuilder中:
optionsBuilder.UseLoggerFactory(_loggerFactory);
答案 1 :(得分:2)
您还需要将ILogger接口添加到Startup.cs
public Startup(IConfiguration configuration, ILogger<Startup> logger, IHostingEnvironment hostingEnvironment)
{
Configuration = configuration;
Logger = logger;
HostingEnvironment = hostingEnvironment;
}
public ILogger<Startup> Logger { get; }
我使用Serilog,它可以与appsetting中的以下选项配合使用
"Serilog": {
"MinimumLevel": {
"Default": "Debug"
}
答案 2 :(得分:1)
如果有帮助,您可以尝试一下。谢谢
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logger => {
logger.AddDebug()
.AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Information);
//logger.AddConsole(); //UnComment out this line if you did not use CreateDefaultBuilder
});
答案 3 :(得分:0)
谢谢您的评论和回答。这里的问题在我的耳边。我最初在问题中发布的代码有效;它将原始SQL记录到Entity SQL查询的调试输出窗口中。
实际上,如果应用程序使用asp.net核心(此功能是Web api应用程序),则所需的资源将更少。默认情况下,Visual Studio 2017作为项目模板的一部分在Program.cs中插入以下代码:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
对CreateDefaultBuilder的调用添加了三种日志记录类型(控制台,调试,事件源),并且还从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);
这成功将原始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
答案 4 :(得分:0)
您可以在Visual Studio Code中运行它,它将显示SQL查询。 VSCode是免费的。您可以在这里下载:Click Here