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
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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
            });

в .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

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