Я только начал изучать LINQ to SQL, и до сих пор меня впечатляет простота использования и хорошая производительность.
Раньше я думал, что при выполнении запросов LINQ, таких как
from Customer in DB.Customers where Customer.Age > 30 select Customer
LINQ получает всех клиентов из базы данных («SELECT * FROM Customers»), перемещает их в массив Customers и затем выполняет поиск в этом массиве с использованием методов .NET. Это очень неэффективно, что если в базе данных есть сотни тысяч клиентов? Выполнение таких больших запросов SELECT убило бы веб-приложение.
Теперь, когда я почувствовал, насколько быстрым является LINQ to SQL, я начинаю подозревать, что при выполнении только что написанного запроса LINQ каким-то образом преобразует его в строку SQL-запроса
SELECT * FROM Customers WHERE Age > 30
И только при необходимости он будет запускать запрос.
Итак, мой вопрос: я прав? И когда на самом деле выполняется запрос?
Причина, по которой я спрашиваю, не только потому, что я хочу понять, как это работает для создания хороших оптимизированных приложений, но и потому, что я столкнулся со следующей проблемой.
У меня есть 2 таблицы, одна из которых - Книги, другая - информация о том, сколько книг было продано в определенные дни. Моя цель - выбрать книги, у которых было как минимум 50 продаж в день за последние 10 дней. Это делается с помощью этого простого запроса:
from Book in DB.Books where (from Sale in DB.Sales where Sale.SalesAmount >= 50 && Sale.DateOfSale >= DateTime.Now.AddDays(-10) select Sale.BookID).Contains(Book.ID) select Book
Дело в том, что мне нужно использовать проверочную часть в нескольких запросах, и я решил создать массив с идентификаторами всех популярных книг:
var popularBooksIDs = from Sale in DB.Sales where Sale.SalesAmount >= 50 && Sale.DateOfSale >= DateTime.Now.AddDays(-10) select Sale.BookID;
НО, когда я пытаюсь сделать запрос сейчас:
from Book in DB.Books where popularBooksIDs.Contains(Book.ID) select Book
Это не работает! Вот почему я думаю, что мы не можем использовать тонкие сочетания клавиш в запросах LINQ to SQL, как мы не можем использовать их в реальном SQL. Мы должны создавать простые запросы, я прав?