In this lesson, you will learn how to configure Entity Framework Core to output precise SQL statements and execution timing directly to your logs for granular performance diagnostics.
When debugging complex data access patterns, the default logging often lacks the depth needed to correlate a specific C# LINQ query with its resulting database round-trip time. By leveraging EF Core's built-in logging provider, we can capture the raw SQL command, the parameter values, and the exact duration of the execution.
Configuring Detailed SQL Logging
To capture this telemetry, you configure the DbContext options during the service registration phase. You must explicitly instruct EF Core to log RelationalEventId.CommandExecuted events, which contain the metadata for SQL execution.
optionsBuilder
.UseSqlServer(connectionString)
.LogTo(Console.WriteLine, new[] { RelationalEventId.CommandExecuted }, LogLevel.Information)
.EnableSensitiveDataLogging(); // Only use in development!
Why Timing and Precision Matter
By setting the log level to Information for CommandExecuted, EF Core automatically injects the duration in milliseconds into the log output. This allows you to identify "N+1" query problems or inefficient joins that might otherwise hide behind the abstraction of your entity models.
When you pair this with EnableSensitiveDataLogging(), EF Core will include the actual parameter values sent to the database instead of the ? placeholders. While this is a powerful diagnostic tool for verifying exactly what values are being passed into your WHERE clauses, never enable this in production, as it can leak PII (Personally Identifiable Information) into your log files.
By observing the logs, you can correlate slow execution times directly to the SQL generated by your LINQ queries. This is the first step in diagnosing why a query that runs instantly in isolation might be dragging down your application's responsiveness under load. Once you identify a bottleneck in the logs, you can analyze the execution plan or refine your query expression tree to optimize the generated SQL.
Key Takeaway: Use RelationalEventId.CommandExecuted in your DbContext configuration to log exact SQL timing and parameter data, providing the transparency needed to bridge the gap between LINQ abstraction and database performance.