Entity Framework 4.0: How to see SQL statements for SaveChanges method

I used to use the context.Log for tracing LINQ to SQL generated SQL Statements as shown in Sql Server Query Visualizer – Cannot see generated SQL Query

context.Log = new OutputWindowWriter();

For EF, is there anything similar and easy like the above approach?

Answers


In general you can hook up the built-in tracer or any logger by simple

context.Database.Log = msg => Trace.WriteLine(msg);

in the DbContext constructor. See more in MSDN. Some other approaches from MS are here (all based on DataContext.Log property).

Talking about the Clutch solution mentioned by Nate, it doesn't work with EF v6 (see this bug-report).

REFERENCES

  1. Logging and Intercepting Database Operations (EF6 Onwards)
  2. Logging and Intercepting Database Operations


The Clutch.Diagnostics.EntityFramework (available in NuGet) works perfectly for me, and it's simpler than the EFTracingProvider.

UPDATE for EF 6:

Starting with Entity Framework 6, anytime Entity Framework sends a command to the database this command can be intercepted by application code. This is most commonly used for logging SQL, but can also be used to modify or abort the command.

Specifically, EF includes: * A Log property for the context similar to DataContext.Log in LINQ to SQL. * A mechanism to customize the content and formatting of the output sent to the log. * Low-level building blocks for interception giving greater control/flexibility.

See http://msdn.microsoft.com/en-US/data/dn469464


The EF Tracing Provider can output all SQL statements executed as traces. You can also use it to add your own logging if you want. Here's some code you could put in the constructor of your context class (this is for a DBContext, but the tweak to use ObjectContext should be pretty apparent):

// enable logging all queries executed by EF
var cx = ((IObjectContextAdapter)this).ObjectContext; // change to var cx = this; if using ObjectContext.
cx.EnableTracing();
cx.Connection.GetTracingConnections().ToList().ForEach(
    c =>
    {
        c.CommandExecuting += (s, e) => Log(e);
        c.CommandFailed += (s, e) => Log(e);
        c.CommandFinished += (s, e) => Log(e);
    });

Lots of solutions to this, but simplest in code is just call ToString() on the IQueryable of the LINQ statement.

var query = db.Employees.Where(x => x.ID = 1); //query will be an IQueryable object
var  sql = query.ToString();

This is only in EF4.1 on (previously calling ToTraceString on the ObjectQuery was the way to achieve this).


Expanding on Nate's answer for EF6, the NLogCommandInterceptor seen in Logging and Intercepting Database Operations only shows the CommandText.

If there was some particular parameter value that caused that commandText to fail, the parameters values aren't emitted to the log. In my case I wanted to log what values were causing Foreign Key violations.

This can be improved by altering NLogCommandInterceptor's LogIfError method like thus

private void LogIfError<TResult>(DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
{
    if (interceptionContext.Exception != null)
    {
        var commandDumper = new DbCommandDumper(command);
        Log.Warn(Command failed:\r\n{0}", commandDumper.GetLogDump());
        // Exception will get logged further up the stack
    }
}

where the DbCommandDumper class reconstructs the DbCommand into TSQL that can be replayed into a test database.


I believe you can use ToTraceString method of the ObjectQuery instance you have. Another approach would be to look at the IntelliTrace of Visual Studion as it logs SQL going out of your project.


Need Your Help

Java: Use DecimalFormat to format doubles and integers but keep integers without a decimal separator

java integer double decimalformat

I'm trying to format some numbers in a Java program. The numbers will be both doubles and integers. When handling doubles, I want to keep only two decimal points but when handling integers I want the

Pathfinding (routing, trip planning, ...) algorithms on graphs with time restrictions

algorithm graph pseudocode path-finding gtfs

I have a database of bus/train/... stops and the arrival/departure times on each date and so on. I'm looking for a way to do a search for the fastest(shortest/cheapest/least transitions) trip betwe...