15

我在“仅代码”模式下使用实体框架 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();

“存储库”属性是 DbContext 的后代。

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

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

4

5 回答 5

19

您可以尝试使用此处描述实体框架跟踪提供程序(但它是 CTP3 的旧帖子)。

您的其他选择是:

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

编辑:

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

于 2011-03-01T12:34:50.793 回答
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();
    }
}

用法:

   var rows = db.Forecasts.Take(1);
   System.Diagnostics.Debug.WriteLine(rows.ToTraceString());
于 2012-09-30T09:15:14.070 回答
3

我要么使用 SQL Trace 直接获取服务器上运行的查询,要么使用ANTS Performance Profiler中的 Event Tracing for Windows (SQL Profiling) 功能。

于 2011-03-01T11:30:30.913 回答
2

设置日志记录非常简单:

context.Database.Log = Console.WriteLine;

原始答案:https ://stackoverflow.com/a/20757916/2183503

于 2016-06-27T23:50:17.670 回答
1

扩展方法 ToTraceString() 可能是您正在寻找的:

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

于 2011-03-01T12:11:20.550 回答