Как получить исходный SQL, лежащий в основе запроса LINQ, когда используется только "код только для Entity Framework CTP 5"?

Я использую 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();

Свойство "Репозиторий" является потомком DbContext.

Это немного сложно, поскольку EF не может использовать мои вспомогательные методы для объектов, поэтому я задаю логику непосредственно в запросе.

Итак, можно ли каким-либо образом сбросить SQL, который будет создан этим запросом LINQ (например, в моем репозитории log4net)?

Ответы

Ответ 1

Я бы использовал SQL Trace для захвата запроса, запущенного на сервере, или использования функции трассировки событий для Windows (SQL Profiling) из ANTS Performance Profiler.

Ответ 2

Вы можете использовать поставщик трассировки Entity Framework в качестве описанный здесь (но это старое сообщение для CTP3).

Другие варианты:

В общем EF вы также можете использовать ToTraceString, поскольку предлагалось @Andy, но DbQuery в CodeFirst не имеет этого метода (или я его не нашел).

Edit:

Итак, DbQuery не имеет ToTraceString, потому что это непосредственно реализовано как ToString.

Ответ 3

Это сработало для меня, и это бесплатно:

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());

Ответ 5

Настройка ведения журнала так же просто, как:

context.Database.Log = Console.WriteLine;

Оригинальный ответ: fooobar.com/info/94544/...