Как получить необработанный 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)?

5 ответов

Решение

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

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

Ваш другой выбор:

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

Редактировать:

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

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

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

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

context.Database.Log = Console.WriteLine;

Оригинальный ответ: /questions/43382034/kak-ya-mogu-zapisat-sgenerirovannyij-sql-iz-dbcontextsavechanges-v-moej-programme/43382052#43382052

Метод расширения ToTraceString() может быть тем, что вы ищете:

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

Другие вопросы по тегам