Logging with .NET Core (and Entity Framework Core) requires some plumbing, and requires you to opt-in to the built-in Dependency Injection infrastructure, which you have to enable manually for application types that are not ASP.NET Core. As you can see from the docs, it can quickly get quite complicated.

The fourth major version of EF Core, named EF Core 5, and currently in preview, finally includes some nice sugar coating to make this much simpler, similar to the Database.Log method in Entity Framework 6.

You can use this, if you simply want to consume the logs from EF in a console app or similar (Windows Service, WinForms, WPF etc). Let's have a closer look.

Create a new .NET Core Console app. with a project file (.csproj) similar to this. The current EF Core 5 preview version is preview 3, but I expect preview 4 to be out very soon. You can see the exact version number on NuGet.Org

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.3.20181.2" />
  </ItemGroup>
  
</Project>

In this sample, I am using the Northwind sample database, so let's add a Shipper class to represent the Shippers table:

public partial class Shipper
{
    public int ShipperId { get; set; }
    public string CompanyName { get; set; }
    public string Phone { get; set; }
}

And let's add a DbContext class:

public partial class NorthwindContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer("Data Source=(localdb)\\mssqllocaldb;Initial Catalog=Northwind;Integrated Security=true");
    }

    public virtual DbSet<Shipper> Shippers { get; set; }
}

Now to enable simple logging to the console of all the log entries EF Core generates, simply add the LogTo method to the optionsBuilder:

optionsBuilder
    .LogTo(Console.WriteLine)
    .UseSqlServer("Data Source=(localdb)\\mssqllocaldb;Initial Catalog=Northwind;Integrated Security=true");

You can use several overloads to customize the logging, for example to only log events in the database category, and set options to format the output, you can do this:

optionsBuilder
    .LogTo(Console.WriteLine, 
        new[] 
        { 
            DbLoggerCategory.Database.Command.Name
        },
        LogLevel.Information, 
        DbContextLoggerOptions.SingleLine | DbContextLoggerOptions.UtcTime)
    .UseSqlServer("Data Source=(localdb)\\mssqllocaldb;Initial Catalog=Northwind;Integrated Security=true");

This will log the SQL generated by EF Core, use UTC time and log everything to a single line:

2020-05-17T09:14:02.5432789Z -> Executed DbCommand (30ms) [Parameters=[], CommandType='Text', CommandTimeout='30']SELECT TOP(1) [s].[Phone]FROM [Shippers] AS [s]WHERE [s].[CompanyName] = N'Speedy Express'

Give EF Core 5 a try today, you can use it with .NET Core 3.1. You cannot use EF Core 5 with classic .NET Framework, as EF Core 5 is a .NET Standard 2.1 library.

Comments or questions for this blog post?