Как получить необработанный SQL, лежащий в основе запроса LINQ, при использовании Entity Framework CTP 5 «только код»? - PullRequest
15 голосов
/ 01 марта 2011

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

19 голосов
/ 01 марта 2011

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

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

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

Edit:

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

10 голосов
/ 30 сентября 2012

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

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());
3 голосов
/ 01 марта 2011

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

1 голос
/ 28 июня 2016

Настройка регистрации так же проста, как:

context.Database.Log = Console.WriteLine;

Оригинальный ответ: https://stackoverflow.com/a/20757916/2183503

1 голос
/ 01 марта 2011

Возможно, вам нужен метод расширения ToTraceString ():

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

...