Извлечь SQL-запрос из выражений LINQ - PullRequest
14 голосов
/ 08 января 2010

Можно ли извлечь операторы sql из запросов LINQ?

Скажите, у меня есть это выражение LINQ.

        string[] names =
            new string[] { "Jon Skeet", "Marc Gravell", "tvanfosson", 
                           "cletus", "Greg Hewgill", "JaredPar" };

        var results = from name in names
                      where name.StartsWith("J")
                      select name;

альтернативный текст http://ruchitsurati.net/files/linq-debugging.png

После этого оператора 'results' содержит только выражение LINQ, а не результаты из-за отложенного выполнения запросов LINQ.

Могу ли я извлечь или произвести запрос LINQ из «результатов» и подготовить действительный оператор SQL из запрос хранится в LINQ?

EDIT

Вот моя цель:

Мы написали нашу собственную ORM. Мы должны писать запросы каждый раз, когда нам нужно выполнять операции с БД. Теперь нам нужно избавиться от этого в DAL. Мы хотим написать выражение LINQ в коде, который будет генерировать операторы SQL для моего ORM, и мы выполним этот SQL в базе данных.

Буду ли я писать свои собственные провайдеры Linq, чтобы делать то, что мне нужно?

Ответы [ 5 ]

22 голосов
/ 08 января 2010

Редактировать: Подождите, вы говорите о LINQ to Objects? Нет, это невозможно 1 . Невозможно преобразовать дерево выражений для запроса LINQ to Object в дерево выражений, которое представляет собой запрос к некоторой базе данных.

Редактировать: не пишите, что вы - собственный ORM. Есть проверенные решения этой проблемы. Вы теряете ценность, пытаясь решить эту проблему снова. Если вы собираетесь использовать свой собственный ORM для преобразования выражения в оператор SQL, то вам придется написать свой собственный поставщик. Вот пошаговое руководство по MSDN.

А если серьезно, не пишите свой собственный ORM. Пять лет назад, до того, как появились NHibernate и LINQ to SQL, все хорошо. Но не сейчас. Ни за что.

В остальной части этого ответа предполагается, что вы спрашивали о LINQ to SQL.

Есть два способа, о которых я знаю.

Во-первых:

Установите для свойства DataContext.Log значение Console.Out (или другое System.IO.TextWriter на ваш выбор):

var db = new MyDataContext();
db.Log = Console.Out;

Это выведет операторы SQL на консоль по мере их выполнения. Подробнее об этой функции см. MSDN . В других местах есть примеров из TextWriter с, которые позволяют отправлять вывод в окно вывода отладчика.

Второе:

Используйте визуализатор отладки LINQ to SQL от Скотта Гатри. Это позволяет просматривать операторы SQL через отладчик в Visual Studio. Эта опция имеет то преимущество, что вы можете видеть оператор SQL без выполнения запроса. Вы даже можете выполнить запрос и просмотреть результаты в визуализаторе.

1 : Возможно, не невозможно, но, конечно, очень сложно.

15 голосов
/ 08 января 2010

РЕДАКТИРОВАТЬ # 2: обновление и уточнение полностью изменили вопрос.

Похоже, вы заново изобретаете колесо и пытаетесь выполнить то, что уже сделали LINQ to SQL и LINQ to Entities. Например, поставщики проверяют деревья выражений и сопоставляют определенные функции с SQL Server. Вы будете выполнять большую задачу, которую Microsoft уже предоставила нам и тщательно протестировала.

Было бы гораздо лучше использовать существующие решения ORM, будь то Microsoft или NHibernate и т. Д.


РЕДАКТИРОВАТЬ # 1: нашел это, я знал, что видел что-то для этого раньше, но это ускользнуло от меня.

Вы можете использовать метод DataContext.GetCommand , чтобы получить сгенерированный SQL:

var query = dc.Persons.Take(1);
string generatedSql = dc.GetCommand(query).CommandText;

В этом примере возвращается следующий SQL из базы данных AdventureWorks:

ВЫБРАТЬ ТОП (1) [T0]. [BusinessEntityID], [t0]. [PersonType], [t0]. [NameStyle], [t0]. [Title], [t0]. [FirstName], [t0]. [MiddleName], [t0]. [LastName], [t0]. [Суффикс], [t0]. [EmailPromotion], [T0]. [AdditionalContactInfo], [t0]. [Демография], [t0]. [rowguid] AS [Rowguid], [t0]. [ModifiedDate] ОТ [Персона]. [Персона] AS [t0]


Другой вариант определения сгенерированных операторов будет доступен в VS2010 через IntelliTrace (ранее известный как Historical Debugger). Для получения дополнительной информации и снимков экрана см. Этот пост в блоге: Отладка запросов LINQ to SQL с использованием Historical Debugger .

Это хорошо только во время отладки, и не дает возможности получить к нему программный доступ.

1 голос
/ 10 ноября 2014

вы можете запустить SQL Server Profiler в вашей базе данных, чтобы отслеживать ваш запрос linq.

0 голосов
/ 22 февраля 2019

Более простой способ, который я нашел, это использовать командное окно, и вам не нужно было вводить дополнительный код. Здесь вы можете напечатать оператор linq под названием query в окне запроса:

? ((System.Data.Objects.ObjectQuery) запрос) .ToTraceString ()

0 голосов
/ 16 апреля 2013

Для дальнейшего использования, я думаю, что этот джентльменский метод лучший

class DebugTextWriter : System.IO.TextWriter {
   public override void Write(char[] buffer, int index, int count) {
       System.Diagnostics.Debug.Write(new String(buffer, index, count));
   }

   public override void Write(string value) {
       System.Diagnostics.Debug.Write(value);
   }

   public override Encoding Encoding {
       get { return System.Text.Encoding.Default; }
   }
}

myDataContext.Log = new DebugTextWriter();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...