LINQ - это широкий набор технологий, основанных (например) на синтаксисе понимания запросов, например:
var qry = from x in source.Foo
where x.SomeProp == "abc"
select x.Bar;
, который отображается компилятором в код:
var qry = source.Foo.Where(x => x.SomeProp == "abc").Select(x => x.Bar);
и здесь начинается волшебство real . Обратите внимание, что мы не сказали, что Foo
здесь - и компилятору все равно! Пока он может разрешить некоторый подходящий метод, называемый Where
, который может принимать лямбду, и в результате этого есть некоторый Select
метод, который может принимать лямбду, он счастливый.
Теперь рассмотрим, что лямбда может быть скомпилирована либо в анонимный метод (делегат, для LINQ-to-Objects, который включает LINQ-to-DataSet), или в дерево выражений (модель времени выполнения, представляющая лямбду в объектной модели).
Для данных в памяти (обычно IEnumerable<T>
) он просто выполняет делегат - отлично и быстро. Но для IQueryable<T>
объектного представления выражения (a LambdaExpression<...>
) он может отделить его и применить к любому примеру "LINQ-to-Something".
Для баз данных (LINQ-to-SQL, LINQ-to-Entities) это может означать написание TSQL, например:
SELECT x.Bar
FROM [SomeTable] x
WHERE x.SomeProp = @p1
Но это может (например, для ADO.NET Data Services) означать написание HTTP-запроса.
Выполнение хорошо написанного запроса TSQL, который возвращает небольшой объем данных, быстрее, чем загрузка всей базы данных по сети и последующая фильтрация на клиенте. У обоих есть идеальные сценарии и сценарии с явной ошибкой.
Целью и преимуществом здесь является предоставление вам возможности использовать один синтаксически проверенный синтаксис для запросов к широкому кругу источников данных и сделать код более выразительным (например, «традиционный» код для группировки данных, не очень понятно с точки зрения того, что он пытается сделать - он теряется в массе кода).