62

I'm using EF 6.0 with LINQ in MVC 5 project. I want to log all the SQL queries executed by the Entity Framework DbContext for debugging/performance-measurement purpose.

In Java/Hibernate, equivalent behavior can be achieved by setting the property hibernate.show_sql=true. Is it possible to have a similar behavior in Entity Framework?

PC.
  • 6,870
  • 5
  • 36
  • 71
  • possible duplicate of [How do I view the SQL generated by the entity framework?](http://stackoverflow.com/questions/1412863/how-do-i-view-the-sql-generated-by-the-entity-framework) – Arion May 22 '14 at 10:58

7 Answers7

86

Logging and Intercepting Database Operations article at MSDN is what your are looking for.

The DbContext.Database.Log property can be set to a delegate for any method that takes a string. Most commonly it is used with any TextWriter by setting it to the “Write” method of that TextWriter. All SQL generated by the current context will be logged to that writer. For example, the following code will log SQL to the console:

using (var context = new BlogContext())
{
    context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

    // Your code here...
}

UPDATE 2022: Logging is now enabled by default in development in ef core. The behavior can be configured in the builder of your DB Context (enable sensitive data logging to log the query parameter values or specify events to be logged ):

      services.AddDbContext<IDbContext, ApplicationDbContext>(
        options => options.UseSqlServer(dbConnectionString)
                          .LogTo(s => System.Diagnostics.Debug.WriteLine(s))
                          .EnableDetailedErrors(isDebugMode)
                          .EnableSensitiveDataLogging(isDebugMode));

or you can use the app.settings file to define logging configuration for events of your interest

Andrew
  • 3,648
  • 1
  • 15
  • 29
  • 31
    fyi: if you use `context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);` then it will only log when in Debug mode. Calls to `System.Diagnostics.Debug` are ignored in Release mode. – Al Dass Oct 20 '15 at 21:26
  • 1
    or you can wrap this line of code into method decorated with `[Conditional("Debug")]` attribute – Andrew Oct 21 '15 at 07:50
  • @Andrew, Can you tell me where this Database.log action is invoked under the hood? –  Jan 29 '17 at 14:33
  • It seems this works but the sql queries generated are parameterized. In debug mode, how would I print the parameterized values? – pingOfDoom May 19 '21 at 15:49
42

You can use this line to log the SQL queries to the Visual Studio "Output" window only and not to a console window, again in Debug mode only.

public class YourContext : DbContext
{   
    public YourContext()
    {
        Database.Log = sql => Debug.Write(sql);
    }
}
Dennis Mieszala
  • 549
  • 4
  • 8
8

If you've got a .NET Core setup with a logger, then EF will log its queries to whichever output you want: debug output window, console, file, etc.

You merely need to configure the 'Information' log level in your appsettings. For instance, this has EF logging to the debug output window:

"Logging": {
  "PathFormat": "Logs/log-{Date}.txt",
  "IncludeScopes": false,
  "Debug": {
    "LogLevel": {
      "Default": "Information",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Console": {
    "LogLevel": {
      "Default": "Information",
      "System": "Warning",
      "Microsoft": "Warning"
    }
  },
  "File": {
    "LogLevel": {
      "Default": "Information",
      "System": "Warning",
      "Microsoft": "Warning"
    }
  },
  "LogLevel": {
    "Default": "Information",
    "System": "Warning",
    "Microsoft": "Warning"
  }
}
Jay
  • 740
  • 4
  • 8
  • 19
5

EF Core logging automatically integrates with the logging mechanisms of .NET Core. Example how it can be used to log to console:

public class SchoolContext : DbContext
{
    //static LoggerFactory object
    public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
              new ConsoleLoggerProvider((_, __) => true, true)
        });

    //or
    // public static readonly ILoggerFactory loggerFactory  = new LoggerFactory().AddConsole((_,___) => true);

    public SchoolContext():base()
    {

    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLoggerFactory(loggerFactory)  //tie-up DbContext with LoggerFactory object
            .EnableSensitiveDataLogging()  
            .UseSqlServer(@"Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;");
    }

    public DbSet<Student> Students { get; set; }
}

If you would like to log to output window use this instead:

public static readonly ILoggerFactory loggerFactory = new LoggerFactory(new[] {
      new DebugLoggerProvider()
});

https://www.entityframeworktutorial.net/efcore/logging-in-entityframework-core.aspx

Ogglas
  • 62,132
  • 37
  • 328
  • 418
3

If someone is using EF6.1+ there is an easy way. Check the below links for more details.

https://learn.microsoft.com/en-us/ef/ef6/fundamentals/configuring/config-file#interceptors-ef61-onwards

Example Code

<interceptors>
  <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
    <parameters>
      <parameter value="C:\Stuff\LogOutput.txt"/>
      <parameter value="true" type="System.Boolean"/>
    </parameters>
  </interceptor>
</interceptors>
Kunal Panchal
  • 1,049
  • 11
  • 19
3

Entity Framework Core 5 and greater

Override OnConfiguring method in YourDbContext with the additional line:

public class YourContext : DbContext
{   
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.LogTo(Console.WriteLine);
    }
}
Grigory Zhadko
  • 1,484
  • 1
  • 19
  • 33
2

Entity Framework Core 3

From this article

Create a factory and set the filter.

var loggerFactory = LoggerFactory.Create(builder =>
{
    builder
    .AddConsole((options) => { })
    .AddFilter((category, level) =>
        category == DbLoggerCategory.Database.Command.Name
        && level == LogLevel.Information);
});

Tell the DbContext to use the factory in the OnConfiguring method:

optionsBuilder.UseLoggerFactory(_loggerFactory);
Christian Findlay
  • 6,770
  • 5
  • 51
  • 103