Используя Entity Framework в .Net Core 2.2, я хотел бы регистрировать все операторы SQL, сгенерированные EF, в окно вывода отладки в 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");
}
@PanagiotisKanavos да, я сделал. Не открывается окно консоли. Исполняемый файл представляет собой веб-API. Когда я запускаю его, открывается экземпляр браузера с путем GET по умолчанию, но окно консоли отсутствует.
Какую платформу ведения журналов вы собираетесь использовать? Вы хотите регистрировать точные операторы SQL или только структуру?
@ Hermann.Gruber Я не понимаю вопроса (новичок в .Net Core). Я хочу регистрировать операторы sql, которые генерирует EF. Если есть что-то, что мне нужно добавить, чтобы выбрать Logging Framework, пожалуйста, дайте мне знать.





вам также необходимо добавить интерфейс ILogger в Startup.cs
public Startup(IConfiguration configuration, ILogger<Startup> logger, IHostingEnvironment hostingEnvironment)
{
Configuration = configuration;
Logger = logger;
HostingEnvironment = hostingEnvironment;
}
public ILogger<Startup> Logger { get; }
Я использую Serilog, и он отлично работает со следующими параметрами в настройках приложения.
"Serilog": {
"MinimumLevel": {
"Default": "Debug"
}
Это ничего не делает. Есть ли шаг, который я пропустил, где мне нужно установить регистратор?
Я думаю да. Может быть, вы хотите попробовать это пошаговое руководство по настройке Serilog с вашим приложением aspnetcore: carlos.mendible.com/2019/01/14/…
Спасибо за упоминание Serilog, я использовал его.
Вы можете попробовать это, если это поможет. Спасибо
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
});
в .Net Core 2.2 метод loggerFactory.AddDebug() устарел.
Когда я тестировал это, он регистрировал запрос в окне вывода. Надеюсь, это поможет. Просто отредактируйте свою программу.cs
Спасибо за комментарии и ответы. Проблема здесь была между моими ушами. Код, который я изначально разместил в своем вопросе, работает; он записывает необработанный SQL в окно вывода отладки для запросов Entity SQL.
На самом деле требуется намного меньше, если приложение использует ядро asp.net (что и делает это, это приложение веб-API). По умолчанию Visual Studio 2017 вставляет следующий фрагмент кода в Program.cs как часть шаблона проекта:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
Вызов CreateDefaultBuilder добавляет 3 типа ведения журнала — Console, Debug, EventSource — а также извлекает раздел «Журналирование» из appsettings.json. Материал «LoggerFactory» в моем исходном вопросе избыточен и не нужен.
Код, который я тестировал и терпел неудачу, хотя и использовал контекст базы данных, выполнял хранимую процедуру с использованием System.Data.Common.DbCommand, которая не передает информацию регистратору, подключенному к DbContext. Мне нужно регистрировать SQL-операторы System.Data.Common.DbCommand вручную (это также необходимо в .Net Framework, но прошло так много лет с тех пор, как я коснулся этого, я забыл).
Когда я создал DbSet в своем DbContext и сделал выбор против него с помощью 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
Я не мог использовать .AddDebug() в своем приложении EFCore 3. Я добавил пакет 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);
Это должен быть принятый ответ. Это, безусловно, самый простой способ получить информацию журнала EF в консоли отладки в EF Core с минимальным изменением того, как вы записывали бы ее в противном случае.
Вы пробовали с
AddConsole()? Это не то же самое, но это поможет изолировать проблему