LINQ - это множество вещей, это комбинация множества более мелких вещей.
Прошу прощения, этот ответ будет беспорядочной информацией. Лучше всего немного подождать и посмотреть, сможет ли кто-нибудь еще лучше описать это, и выполнить поиск в Google по ключевым словам, которые я использую.
LINQ означает « L anguage IN tegrated Q uery», и наиболее наивная интерпретация заключается в том, что они добавили синтаксис, подобный SQL, в язык программирования C #.
Итак, вместо:
IEnumerable<int> values = otherValues.Where(i => i > 5);
у них есть синтаксис:
IEnumerable<int> values = from i in otherValues
where i > 5
select i;
Компилятор C # фактически преобразует второй фрагмент кода выше в первый фрагмент кода, так что на самом деле вы просто вызываете методы в коллекциях .
Однако и вот еще одна часть загадки. Эти методы вообще не определены в коллекциях. Они определены как методы расширения, что означает, что они определены где-то в другом месте, с некоторой уловкой, которая в основном гласит: «Позвольте программисту использовать эти методы, как если бы они были определены в типе коллекции для начала, и просто исправьте код во время компиляции. ".
Итак, первый фрагмент кода выше:
IEnumerable<int> values = otherValues.Where(i => i > 5);
фактически завершается компиляцией как:
IEnumerable<int> values = Enumerable.Where(otherValues, i => i > 5);
Метод Where определен здесь: Enumerable.Where .
Следующее волшебство заключается в том, что компилятор C # не использует Enumerable. Он просто переписывает код на лету, чтобы он выглядел как второй фрагмент кода в моем ответе, и пусть нормальный вывод типа выработайте это.Другими словами, он будет притворяться, что вы действительно написали второй фрагмент кода, а затем увидит, что «otherValues» - это List
, где T
- это int
, а затем найдите, что Enumerable.Where
- тот, который нужно вызвать.
Это означает, что для типов, отличных от коллекций, вы можете создать свои собственные реализации Where, и синтаксис LINQ будет никуда не годиться.
Это означает ... что могут быть запрошены вещи, которые на самом деле не являются коллекциями в памяти. Например, если "otherValues" выше - это то, что умеет получать данные из базы данных, будет вызван другой метод Where, а не метод Enumerable.Where.
Это позволяет этим другим реализациям делать свои дела по-своему, например, писать за вас SQL, выполнять его и упаковывать результат так, чтобы он смотрел на вызывающий код, как если бы он на самом деле был входящим. сбор памяти для начала.
Следующее волшебство - это выражения. Параметр метода Where выше, i => i> 5
, в большинстве случаев является лямбда-выражением или анонимным методом, и вы можете фактически объявить его так для коллекции в памяти:
Func<int, bool> w = delegate(int i) { return i > 5; };
IEnumerable<int> values = otherValues.Where(w);
Однако поддержка выражения в C # означает, что вы также можете объявить его как:
Expression<Func<int, bool>> w = i => i > 5;
Здесь компилятор на самом деле не сохраняет его как скомпилированный фрагмент кода, а скорее как структуру данных в памяти, которая знает, что она принимает один аргумент, сравнивает его с 5 с помощью сравнения «больше чем» и возвращает результат. Обратите внимание, что вы должны использовать лямбда-способ записи, а не в качестве делегата.
Это знание позволяет другим реализациям Where, если они объявлены как принимающие выражения, не только ухватиться за «предложение where», но и посмотреть на него, выделить его и переписать.
Это означает, что создание этого SQL может быть выполнено с помощью метода Where, который знает, как работать с кодом SQL.
Вот объявление LINQ to SQL метода Where: Queryably.Where .
Итак, LINQ - это комбинация множества небольших технологий, добавленных к компилятору C #:
MSDN отлично справляется с внедрением LINQ:
[...]
Интегрированный в язык запрос .NET определяет набор стандартов общего назначения операторы запросов, которые позволяют обход, фильтровать и проецировать быть выраженным в прямом еще декларативным образом в любом .NET-ориентированном язык программирования. Стандарт операторы запросов позволяют выполнять запросы применяется к любому основанному на IEnumerable Информационный ресурс. LINQ позволяет третьему стороны, чтобы пополнить набор стандартных операторы запросов с новыми доменные операторы, которые подходит для целевого домена или технологии. Что еще более важно, в-третьих стороны также могут заменить стандартные операторы запросов с их собственные реализации, которые обеспечивают дополнительные услуги, такие как удаленный оценка, перевод запроса, оптимизация и так далее.Придерживаясь к соглашениям LINQ паттерн, такие реализации пользуются та же языковая интеграция и инструмент поддержка как стандартный запрос операторы.
[...]
Это несколько разных вещей.
Linq, как он появляется в пространстве имен System.Linq - это набор методов расширения, которые позволяют вам запрашивать коллекции непосредственно в коде. Это аббревиатура от "Language INtegrated Query".
Это также набор провайдеров, позволяющих запрашивать различные источники данных - SQL с помощью Linq to SQL, XML с помощью Linq to XML и т. д.
Считайте это запросом к объектам с использованием sql-подобного синтаксиса. Вот пример, скопированный из http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
public void Linq1()
{
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var lowNums =
from n in numbers
where n < 5
select n;
Console.WriteLine("Numbers < 5:");
foreach (var x in lowNums)
{
Console.WriteLine(x);
}
}
Linq - это набор методов расширения IEnumerable. Он предназначен для абстрагирования от некоторых деталей получения объектов из коллекций. Когда вы "запрашиваете" коллекцию с помощью Linq, вы делаете это декларативно, а не императивно. Это означает, что ваш запрос Linq показывает то, что вы хотите получить, а не то, как именно вы собираетесь это получить. В цикле foreach() вам придется четко представлять, как вы собираетесь фильтровать, группировать и сортировать результаты. В Linq это всего лишь несколько коротких утверждений, а детали реализации абстрагированы от вас.
У многих людей сложилось неверное представление, что он имеет отношение к SQL из-за Linq-to-Sql, но на самом деле это лишь одна небольшая часть Linq. Вам не обязательно использовать L2S, чтобы получить всю мощь Linq, и на самом деле многие люди этого не делают. Хотя Linq-to-SQL, по моему личному мнению, является "кошачьим мяуканьем", если вы работаете на .NET с SQL Server в качестве БД.