Explain Codes LogoExplain Codes Logo

How can I log the generated SQL from DbContext.SaveChanges() in my Program?

csharp
entity-framework
logging
interceptors
Alex KataevbyAlex Kataev·Feb 10, 2025
TLDR

For ready-to-go logging of SQL from DbContext.SaveChanges() in EF Core, you'll want to hook up an ILoggerFactory to capture SQL commands. This nifty bit of code in your DB context setup will do the trick:

optionsBuilder.UseLoggerFactory( LoggerFactory.Create(builder => builder .AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Information) .AddConsole() ) );

This informs EF Core to dispatch information-level events for database commands straight to your console. Save changes, and voila! The elusive SQL springs forth in your output.

Log without attachments

When working with Entity Framework 6 (the cool older sibling of EF Core), logging is as easy as defining the Database.Log property. Just watch:

using (var context = new YourDbContext()) { context.Database.Log = Console.WriteLine; // Loud and proud to console context.SaveChanges(); }

But wait, what if you crave more control? When it's time to go pro, it's time for some interceptors.

Detailed Logging (What's up, Interceptor?)

Interceptors enable deep dives into the EF's operations. Here's your quick guide to IDbCommandInterceptor:

  1. Make your interceptor:

    public class EFCommandInterceptor : IDbCommandInterceptor { public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { LogQuery(command); // Like a boss! } // Your other method... }
  2. Interceptor, reporting for duty!

    DbInterception.Add(new EFCommandInterceptor());
  3. Log like you've never logged before:

    private void LogQuery(DbCommand command) { // Play detective on SQL and parameters, or twist the command Debug.WriteLine(command.CommandText); }

Sensitive environment, handle with care!

In a production environment, be sure to tuck in your logging setup with environment checks to dodge those nasty performance hits:

if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") { context.Database.Log = Console.WriteLine; // Whisper only in Development! }

Creating your own destiny (and logs)

For some added sparkle:

  • Muster lambda expressions like x => Debug.WriteLine(x) to lead your log output where you desire.
  • Memorable logs are forged with System.IO.File.AppendAllText and the right checks for thread safety and scalability, of course.

Don't rain on your log parade

Commit to register interceptors once or prepare for log overload:

if (!DbInterception.Contains<EFCommandInterceptor>()) { DbInterception.Add(new EFCommandInterceptor()); // My log, my rules! }

Common Pitfalls: Not for the faint-hearted

In your logging adventures, be on guard for:

  • Exposing sensitive data: Clean your logs before you publicize or store them.
  • Performance Missteps: Logging costs resources, so keep it conditional. Start detailed logs only in debugging sessions.
  • Concurrency Chills: When logging to a file or a shared hub, synchronized or thread-safe methods keep conflicts at bay.