# LINQ

LINQ (Language-Integrated Query) представляет простой и удобный язык запросов к источнику данных. В качестве источника данных может выступать объект, реализующий интерфейс IEnumerable (например, стандартные коллекции, массивы), набор данных DataSet, документ XML. Но вне зависимости от типа источника LINQ позволяет применить ко всем один и тот же подход для выборки данных.

Существует несколько разновидностей LINQ:

* LINQ to Objects: применяется для работы с массивами и коллекциями
* LINQ to Entities: используется при обращении к базам данных через технологию Entity Framework
* LINQ to Sql: технология доступа к данным в MS SQL Server

Вы можете писать запросы LINQ в C# для обращения к базам данных SQL Server, XML-документам, наборам данных ADO.NET и любым коллекциям объектов, поддерживающим интерфейс [IEnumerable](https://docs.microsoft.com/ru-ru/dotnet/api/system.collections.ienumerable) или универсальный интерфейс [IEnumerable\<T>](https://docs.microsoft.com/ru-ru/dotnet/api/system.collections.generic.ienumerable-1).Кроме того, сторонние разработчики обеспечивают поддержку LINQ для множества веб-служб и других реализаций баз данных.

### Преобразование запросов <a href="#query-conversion" id="query-conversion"></a>

Для выполнения запроса в технологии LINQ to Entities на платформе Entity Framework запрос LINQ нужно преобразовать в дерево команд, которое можно выполнить на платформе Entity Framework.

Запросы LINQ to Entities состоят из стандартных операторов запросов LINQ (такие как [Select](https://docs.microsoft.com/ru-ru/dotnet/api/system.linq.queryable.select), [Where](https://docs.microsoft.com/ru-ru/dotnet/api/system.linq.queryable.where), и [GroupBy](https://docs.microsoft.com/ru-ru/dotnet/api/system.linq.queryable.groupby)) и выражений (x > 10, Contact.LastName и т. д.). Операторы LINQ не определяются классом, а являются методами класса. В LINQ выражения могут содержать любые конструкции, допустимые для типов в пределах пространства имен [System.Linq.Expressions](https://docs.microsoft.com/ru-ru/dotnet/api/system.linq.expressions), а по расширению - любые конструкции, которые могут быть представлены лямбда-функциями. Это надмножество выражений, допустимых для платформы Entity Framework, множество которых по определению ограничено допустимыми операциями над базой данных и поддерживается посредством [ObjectQuery\<T>](https://docs.microsoft.com/ru-ru/dotnet/api/system.data.objects.objectquery-1).

На платформе Entity Framework и операторы, и выражения представляются одной иерархией типов, которая затем помещается в дерево команд. Дерево команд используется платформой Entity Framework для выполнения запроса. Если запрос LINQ не удается выразить в виде дерева команд, при преобразовании запроса будет создано исключение.Преобразование запросов LINQ to Entities включает два промежуточных преобразования - стандартных операторов запросов и выражений.

#### Список используемых методов расширения LINQ

* Select: определяет проекцию выбранных значений
* Where: определяет фильтр выборки
* OrderBy: упорядочивает элементы по возрастанию
* OrderByDescending: упорядочивает элементы по убыванию
* ThenBy: задает дополнительные критерии для упорядочивания элементов возрастанию
* ThenByDescending: задает дополнительные критерии для упорядочивания элементов по убыванию
* Join: соединяет две коллекции по определенному признаку
* GroupBy: группирует элементы по ключу
* ToLookup: группирует элементы по ключу, при этом все элементы добавляются в словарь
* GroupJoin: выполняет одновременно соединение коллекций и группировку элементов по ключу
* Reverse: располагает элементы в обратном порядке
* All: определяет, все ли элементы коллекции удовлятворяют определенному условию
* Any: определяет, удовлетворяет хотя бы один элемент коллекции определенному условию
* Contains: определяет, содержит ли коллекция определенный элемент
* Distinct: удаляет дублирующиеся элементы из коллекции
* Except: возвращает разность двух коллекцию, то есть те элементы, которые содератся только в одной коллекции
* Union: объединяет две однородные коллекции
* Intersect: возвращает пересечение двух коллекций, то есть те элементы, которые встречаются в обоих коллекциях
* Count: подсчитывает количество элементов коллекции, которые удовлетворяют определенному условию
* Sum: подсчитывает сумму числовых значений в коллекции
* Average: подсчитывает cреднее значение числовых значений в коллекции
* Min: находит минимальное значение
* Max: находит максимальное значение
* Take: выбирает определенное количество элементов
* Skip: пропускает определенное количество элементов
* TakeWhile: возвращает цепочку элементов последовательности, до тех пор, пока условие истинно
* SkipWhile: пропускает элементы в последовательности, пока они удовлетворяют заданному условию, и затем возвращает оставшиеся элементы
* Concat: объединяет две коллекции
* Zip: объединяет две коллекции в соответствии с определенным условием
* First: выбирает первый элемент коллекции
* FirstOrDefault: выбирает первый элемент коллекции или возвращает значение по умолчанию
* Single: выбирает единственный элемент коллекции, если коллекция содердит больше или меньше одного элемента, то генерируется исключение
* SingleOrDefault: выбирает первый элемент коллекции или возвращает значение по умолчанию
* ElementAt: выбирает элемент последовательности по определенному индексу
* ElementAtOrDefault: выбирает элемент коллекции по определенному индексу или возвращает значение по умолчанию, если индекс вне допустимого диапазона
* Last: выбирает последний элемент коллекции
* LastOrDefault: выбирает последний элемент коллекции или возвращает значение по умолчанию
