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

后端 未结 6 707
长发绾君心
长发绾君心 2020-12-09 02:26

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

conte         


        
相关标签:
6条回答
  • 2020-12-09 02:34

    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).

    0 讨论(0)
  • 2020-12-09 02:46

    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

    0 讨论(0)
  • 2020-12-09 02:46

    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.

    0 讨论(0)
  • 2020-12-09 02:47

    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

    0 讨论(0)
  • 2020-12-09 02:56

    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.

    0 讨论(0)
  • 2020-12-09 02:58

    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);
        });
    
    0 讨论(0)
提交回复
热议问题