How do I get the raw SQL underlying a LINQ query when using Entity Framework CTP 5 "code only"?
Asked Answered
C

5

16

I've using Entity Framework CTP5 in "code only" mode. I'm running a LINQ query on a object that was return from the database, as the query is running really slowly. Is there any way in which I can get the SQL statement that is being generated from the query?

Topic currentTopic =
    (from x in Repository.Topics
     let isCurrent = (x.StoppedAt <= x.StartedAt || (x.StartedAt >= currentTopicsStartedAtOrAfter))
     where x.Meeting.Manager.User.Id == user.Id && isCurrent
     orderby x.StartedAt descending
     select x).FirstOrDefault();

The "Repository" property is a descendent of DbContext.

It's a little complicated, as EF can't use my helper methods on the objects, so I'm specifying the logic directly in the query.

So, is there any way I can dump the SQL that will be produced by that LINQ query (e.g. to my log4net repository)?

Closestool answered 1/3, 2011 at 11:19 Comment(2)
I can't help you with the SQL dump, but I'm curious as to why EF can't use your helper methods on the objects. How have you defined the helpers?Undetermined
Well, I have a IsCurrent property on the topic, that is defined as "return (StoppedAt <= StartedAt || (DateTime.Now - StartedAt).TotalHours <= ExpirationPeriodHours)". If I use that in the query (i.e. x.IsCurrent), it won't execute.Closestool
C
3

I'd either use SQL Trace to grab the query running on the server directly, or use the Event Tracing for Windows (SQL Profiling) feature out of ANTS Performance Profiler.

Chloroform answered 1/3, 2011 at 11:30 Comment(0)
A
19

You can try using Entity Framework tracing provider as described here (but it is old post for CTP3).

Your other choices are:

In common EF you can also use ToTraceString as @Andy suggested but DbQuery in CodeFirst doesn't have this method (or I didn't find it).

Edit:

So DbQuery doesn't have ToTraceString because it is directly implemented as ToString.

Assassin answered 1/3, 2011 at 12:34 Comment(2)
+1 for .ToString() - took me 15 minutes to find this post and 2 seconds to actually see my query! i like itMalefic
When I use DbQuery.ToString(), the SQL it returns doesn't fill in the parameters. In other words it contains a bunch of "@p__linq__0". Am I the only one who sees this?Farflung
S
10

This worked for me and it is free:

public static class DebugExtensions
{
    private static object GetPropertyValue(object o, string Name)
    {
        return o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(x => x.Name == Name).First().GetValue(o, null);
    }
    public static string ToTraceString(this IQueryable query)
    {
        var oquery = (ObjectQuery)GetPropertyValue(GetPropertyValue(query, "InternalQuery"), "ObjectQuery");
        return oquery.ToTraceString();
    }
}

Usage:

   var rows = db.Forecasts.Take(1);
   System.Diagnostics.Debug.WriteLine(rows.ToTraceString());
Shingles answered 30/9, 2012 at 9:15 Comment(0)
C
3

I'd either use SQL Trace to grab the query running on the server directly, or use the Event Tracing for Windows (SQL Profiling) feature out of ANTS Performance Profiler.

Chloroform answered 1/3, 2011 at 11:30 Comment(0)
A
2

Setting up logging is as easy as:

context.Database.Log = Console.WriteLine;

Original answer: https://mcmap.net/q/233866/-how-can-i-log-the-generated-sql-from-dbcontext-savechanges-in-my-program-duplicate

Annals answered 27/6, 2016 at 23:50 Comment(0)
E
1

The extension method ToTraceString() might be what you're looking for:

http://msdn.microsoft.com/en-us/library/system.data.objects.objectquery.totracestring.aspx

Enchiridion answered 1/3, 2011 at 12:11 Comment(1)
This won't work because he's using a DbContext, which uses DbSet and DbQuery, as opposed to an ObjectContext, which uses ObjectQuery.Farflung

© 2022 - 2024 — McMap. All rights reserved.