LINQ и созданный sql

предположим, что мой запрос LINQ похож на

var qry = from c in nwEntitiesContext.CategorySet.AsEnumerable()  
           let products = this.GetProducts().WithCategoryID(c.CategoryID)  
           select new Model.Category  
           {  
               ID = c.CategoryID,  
               Name = c.CategoryName,  
               Products = new Model.LazyList<Core.Model.Product>(products)  

           };  
 return qry.AsQueryable();  

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


person Mou    schedule 29.04.2011    source источник


Ответы (3)


Попробуйте Linqpad

person jjchiw    schedule 29.04.2011
comment
без использования linq pad мы не можем увидеть сгенерированный sql. поскольку иногда получение данных происходит медленно, пользователю определенно нравится видеть, что генерирует sql. пожалуйста посоветуй. - person Mou; 29.04.2011
comment
@ user728750 - вы не показываете код для GetProducts(), но если вы делаете запрос EF для получения всех продуктов с определенным идентификатором categoryId, это может привести к вызову DB для КАЖДОГО Category в БД. После того, как вы позвонили AsEnumerable, вы попадаете в объектное пространство (EF сделал запрос и выбрал все категории). После этого, в зависимости от того, что вы делаете, вы действительно можете делать запрос к БД для каждой категории, который объяснит проблемы с производительностью, с которыми вы сталкиваетесь. Вы можете проверить, что происходит на уровне SQL, запустив, например, SQL Profiler (см. Мой ответ). - person Yakimych; 29.04.2011

Здесь особо не на что смотреть - он просто выберет все поля из таблицы Category, поскольку вы вызываете AsEnumerable, таким образом извлекая все данные из таблицы Category в память. После этого вы находитесь в пространстве объектов. Ну, в зависимости от того, что делает this.GetProducts() - и я предполагаю, что он делает другой запрос EF, извлекающий результаты в память. В таком случае я настоятельно рекомендую вам задать еще один вопрос с этим кодом и кодом вашего GetProducts метода, чтобы мы могли взглянуть и переписать его более оптимальным образом. (Помимо этого, вы проецируетесь на сопоставленную сущность Model.Category, которая снова не будет (и не должна) работать с Linq-to-Entities.)

Перед тем, как прочитать ваш запрос, я собирался порекомендовать сделать что-то вроде этого:

string sqlQueryString = ((ObjectQuery)qry).ToTraceString();

Но это не сработает, поскольку вы смешиваете Linq-to-Entities с Linq-to-объектами, и на самом деле у вас будет несколько запросов, выполненных в случае GetProducts запросов EF. Вы можете отделить эту часть своим EF-запросом и увидеть SQL следующим образом:

string sqlString = nwEntitiesContext.CategorySet.ToTraceString();

но, как я упоминал ранее, это просто выберет все из таблицы Categories.

В вашем случае (если вы не переписываете свой код радикальным образом) вы действительно хотите видеть, какие запросы выполняются против БД, когда вы выполняете код и перечисляете результаты запросов. См. Этот вопрос: точный запрос sql, выполняемый Entity Framework

Вы можете выбрать SQL Server Profiler и Entity Framework Profiler. Вы также можете попробовать LinqPad, но в целом я все же рекомендую вам более подробно описать, что делают ваши запросы (и, скорее всего, переписать их более оптимальным образом, прежде чем продолжить).

person Yakimych    schedule 29.04.2011

Это произведет SELECT * FROM Categories. Больше ничего. Как только вы вызываете AsEnumerable, вы попадаете в Linq-to-objects, и нет возможности вернуться к Linq-to-entity (AsQueryable этого не делает).

Если вы хотите узнать, какой запрос создается, используйте SQL Profiler или любой метод, описанный в этой статье.

person Ladislav Mrnka    schedule 29.04.2011