Подтвердить что ты не робот

Извлечь sql-запрос из выражений LINQ

Можно ли извлекать 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;

alt text http://ruchitsurati.net/files/linq-debugging.png

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

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

ИЗМЕНИТЬ

Здесь моя цель:

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

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

4b9b3361

Ответ 1

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

Изменить: не пишите, что у вас собственный ОРМ. Существуют проверенные решения этой проблемы. Вы теряете ценность, пытаясь снова решить эту проблему. Если вы собираетесь использовать свой собственный 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 Debug Visualizer от Скотта Гатри. Это позволяет вам видеть инструкции SQL через отладчик в Visual Studio. Преимущество этой опции состоит в том, что вы можете увидеть инструкцию SQL без выполнения запроса. Вы даже можете выполнить запрос и увидеть результаты в визуализаторе.

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

Ответ 2

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

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

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


EDIT # 1: нашел это, я знал, что видел что-то для этого раньше, но это ускользнуло меня.

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

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

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

SELECT TOP (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] FROM [Лицо]. [Лицо] AS [t0]


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

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

Ответ 3

вы можете запустить профилировщик SQL Server в своей базе данных для отслеживания вашего запроса linq.

Ответ 4

В будущем, я думаю, этот метод джентльмена является лучшим http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-or-multiple-writers

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