Log Entity Framework .Net Core 2.2 EF для отладки выходного окна

Используя 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");
    }

Вы пробовали с AddConsole() ? Это не то же самое, но это поможет изолировать проблему

Panagiotis Kanavos 22.05.2019 17:21

@PanagiotisKanavos да, я сделал. Не открывается окно консоли. Исполняемый файл представляет собой веб-API. Когда я запускаю его, открывается экземпляр браузера с путем GET по умолчанию, но окно консоли отсутствует.

Tom Regan 22.05.2019 17:22

Какую платформу ведения журналов вы собираетесь использовать? Вы хотите регистрировать точные операторы SQL или только структуру?

Hermann.Gruber 22.05.2019 17:23

@ Hermann.Gruber Я не понимаю вопроса (новичок в .Net Core). Я хочу регистрировать операторы sql, которые генерирует EF. Если есть что-то, что мне нужно добавить, чтобы выбрать Logging Framework, пожалуйста, дайте мне знать.

Tom Regan 22.05.2019 17:23
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
4
4
6 594
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

вам также необходимо добавить интерфейс 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"
    }

Это ничего не делает. Есть ли шаг, который я пропустил, где мне нужно установить регистратор?

Tom Regan 22.05.2019 17:40

Я думаю да. Может быть, вы хотите попробовать это пошаговое руководство по настройке Serilog с вашим приложением aspnetcore: carlos.mendible.com/2019/01/14/…

Hermann.Gruber 22.05.2019 18:13

Спасибо за упоминание Serilog, я использовал его.

Tom Regan 24.05.2019 15:02

Вы можете попробовать это, если это поможет. Спасибо

 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
            });

enter image description here

в .Net Core 2.2 метод loggerFactory.AddDebug() устарел.

Tom Regan 22.05.2019 17:53

Когда я тестировал это, он регистрировал запрос в окне вывода. Надеюсь, это поможет. Просто отредактируйте свою программу.cs

Samuel Akosile 22.05.2019 18:42
Ответ принят как подходящий

Спасибо за комментарии и ответы. Проблема здесь была между моими ушами. Код, который я изначально разместил в своем вопросе, работает; он записывает необработанный 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 с минимальным изменением того, как вы записывали бы ее в противном случае.

EGP 09.05.2020 21:42

Другие вопросы по теме