Цель провайдера Linq состоит в том, чтобы в основном «перевести» деревья выражений Linq (которые создаются за кулисами запроса) на родной язык запросов источника данных. В тех случаях, когда данные уже находятся в памяти, вам не нужен поставщик Linq; Linq 2 Объекты в порядке. Однако, если вы используете Linq для связи с внешним хранилищем данных, таким как СУБД или облако, это абсолютно необходимо.
Основная предпосылка любой структуры запросов состоит в том, что механизм источника данных должен выполнять как можно большую часть работы и возвращать только те данные, которые необходимы клиенту. Это связано с тем, что источник данных, как предполагается, лучше знает, как управлять хранящимися в нем данными, а также потому, что передача данных по сети является относительно дорогостоящей во времени и поэтому должна быть минимизирована. Теперь, на самом деле, эта вторая часть «возвращает только те данные, которые запрашивает клиент»; сервер не может читать мысли вашей программы и знать, что ей действительно нужно; он может дать только то, что просил. Вот где интеллектуальный провайдер Linq просто поражает «наивной» реализацией. Используя IQueryable сторону Linq, которая генерирует деревья выражений, поставщик Linq может преобразовать дерево выражений, скажем, в оператор SQL, который СУБД будет использовать для возврата записей, которые клиент запрашивает в операторе Linq. Наивная реализация потребовала бы извлечения ВСЕХ записей с использованием некоторого широкого оператора SQL, чтобы предоставить клиенту список объектов в памяти, а затем вся работа по фильтрации, группировке, сортировке и т. Д. Выполняется клиентом.
Например, предположим, что вы использовали Linq для получения записи из таблицы в БД по ее первичному ключу. Поставщик Linq может перевести dataSource.Query<MyObject>().Where(x=>x.Id == 1234).FirstOrDefault()
в «SELECT TOP 1 * из MyObjectTable WHERE Id = 1234». Это возвращает ноль или одну запись. «Наивная» реализация, вероятно, будет отправлять серверу запрос «SELECT * FROM MyObjectTable», а затем использовать сторону IEnumerable Linq (которая работает с классами в памяти) для выполнения фильтрации. В утверждении, которое вы ожидаете получить 0-1 из таблицы с 10 миллионами записей, какие из них, по вашему мнению, будут выполнять работу быстрее (или даже работать вообще, без нехватки памяти)?