在使用Entity Framework CTP 5"仅代码"时,如何获取LINQ查询的原始SQL?

dom*_*mer 15 sql profiling entity-framework code-first ef4-code-only

我在"仅代码"模式下使用Entity Framework CTP5.我正在对从数据库返回的对象运行LINQ查询,因为查询运行速度非常慢.有什么方法可以让我从查询中获取生成的SQL语句?

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();
Run Code Online (Sandbox Code Playgroud)

"Repository"属性是DbContext的后代.

这有点复杂,因为EF无法在对象上使用我的辅助方法,所以我直接在查询中指定逻辑.

那么,有什么方法可以转储由LINQ查询生成的SQL(例如,我的log4net存储库)?

Lad*_*nka 19

您可以尝试使用实体框架跟踪提供商这里所描述的(但它是旧的职位CTP3).

您的其他选择是:

在常见的EF中,您也可以使用ToTraceString@Andy建议,但DbQuery在CodeFirst中没有这种方法(或者我没有找到它).

编辑:

所以DbQuery没有,ToTraceString因为它直接实现ToString.

  • 当我使用DbQuery.ToString()时,它返回的SQL不会填充参数.换句话说,它包含一堆"@ p__linq__0".我是唯一一个看到这个的人吗? (6认同)
  • .ToString()的+1 - 花了我15分钟找到这篇文章和2秒实际看到我的查询!我喜欢 (3认同)

Joh*_*ohn 10

这对我有用,而且是免费的:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

   var rows = db.Forecasts.Take(1);
   System.Diagnostics.Debug.WriteLine(rows.ToTraceString());
Run Code Online (Sandbox Code Playgroud)


Mel*_*our 3

我要么使用 SQL Trace 直接获取服务器上运行的查询,要么使用ANTS Performance Profiler中的 Windows 事件跟踪(SQL 分析)功能。