Loading AI tools
З Вікіпедії, вільної енциклопедії
LINQ (англ. Language Integrated Query - запити, інтегровані в мову) - компонент Microsoft .NET Framework, який додає нативні можливості виконання запитів даних до мов, що входять у .NET. Хоча порти існують для PHP (PHPLinq), JavaScript(linq.js), TypeScript (linq.ts), і ActionScript (ActionLinq), - жоден з них не є абсолютно еквівалентним LINQ в C# (де LINQ - не просто додаткова бібліотека, а частина мови).
LINQ розширює можливості мови, додаючи до неї вирази запитів, що є схожими на твердження SQL та можуть бути використані для зручного отримання та обробки даних масивів, XML документів, реляційних баз даних та сторонніх джерел. LINQ також визначає набір імен методів (що називаються стандартними операторами запитів, або стандартними операторами послідовностей), а також правила перекладу, що має використовувати компілятор для перекладу текучих виразів у звичайні, використовуючи їх назву, лямбда-вирази та анонімні типи[en].
Багато концептів, що представлені у LINQ, були спершу випробувані у дослідницькому проєкті Microsoft Cω. LINQ був випущений як частина .NET Framework 3.5 19 листопада 2007 року.
Далі описано роботу операторів з колекціями. Багато операторів приймають у якості аргументу функції. Ці функції можуть бути представлені як у вигляді іменованого методу, так і анонімної функції.
Набір операторів запитів, що визначені в LINQ, надається користувачу у вигляді API. Оператори запитів, що підтримуються API[1]:
Select
Даний оператор виконує проєкцію на колекцію, щоб отримати необхідні члени елементів. Користувач передає у якості параметру довільну функцію у вигляді лямбда-виразу, що проєктує члени даного об'єкту. Функція передається до оператора у вигляді делегату.
Where
Оператор Where дозволяє визначити набір предикатів, що виконуються над кожним елементом колекції та відкидає елементи, що не підпадають під задану умову з результуючого набору. Предикат передається до оператора у вигляді делегату.
SelectMany
SelectMany використовується для створення вихідної колекції згідно заданої користувачем проєкції з вхідних колекцій.
Sum / Min / Max / Average
Дані оператори можуть приймаюти функцію, яка співставляє кожне значення колекції з певним числом, після чого можна знайти їх суму, мінімальне, максимальне, або середнє значення. Перевантажені версії даних методів не приймають функцій на вхід, а виконують відповідні дії над самими елементами колекції.
Aggregate
Узагальнений оператор Sum / Min / Max. Він приймає у якості аргументу функцію, що вказує яким чином треба поєднати два елементи, щоб утворити проміжний, або кінцевий результат. Додатково можна задати початкове значення. Крім цього, можна задати завершальну функцію, що перетворить результат агрегації на фінальне значення.
Join / GroupJoin
Оператор Join виконує inner join щодо двох колекцій, орієнтуючись на співпадаючі ключі для об'єктів з обидвох колекцій. Він приймає дві функції у вигляді делегатів, по одній для кожної колекції, а потім застосовує їх до кожного елемента відповідної колекції, щоб отримати їх ключі. Він також отримує інший делегат, у якому користувач вказує які члени вхідних об'єктів повинні міститися у результуючому наборі. Оператор GroupJoin виконує group join. Так як і оператор Select, результати з'єднання є екземплярами класу, чиї поля збігаються з полями вхідних об'єктів, або є їх підммножиною.
Take / TakeWhile
Оператор Take повертає перші n елементів колекції, тоді як TakeWhile повертає не більше n перших послідовних елементів, що підпадають під умови предикату.
Skip / SkipWhile
Аналогічно до Take та TakeWhile, дані оператори відповідно пропускають перші n елементів, або не більше n перших послідовних елементів, що відповідають предикату.
OfType
Використовується для отримання елементів певного типу.
Concat
Даний оператор конкатенує дві колекції.
OrderBy / ThenBy
Оператор OrderBy дозволяє задати порядок сортування елементів в колекції по певному ключу. За умовчанням сортування відбувається у порядку зростання. Для сортування по спаданню, треба використовувати оператор OrderByDescending. ThenBy and ThenByDescending дозволяють задати правила сортування підпослідовностей. Сортування відбувається по ключу, що користувач передав в якості делегату.
Reverse
Даний оператор повертає елементи колекції в зворотньому порядку.
GroupBy
Оператор GroupBy приймає у якості параметру функцію, що по певному ключу повертає колекцію об'єктів IGrouping<Key, Values>
для кожного унікального значення ключа. Об'єкти IGrouping
можна використати для перечислення всіх елементів з певним ключем.
Distinct
Оператор вилучає дублікати елементів з колекції. Перевантажена версія оператору приймає у якості аргументу об'єкт, що здійснює перевірку елементів на рівність.
Union / Intersect / Except
Дані оператори використовуються, щоб виконати операції об'єднання, перетину та різниці над двома послідовностями. Кожен з них має перевантажену версію, що приймає об'єкт, який перевіряє на рівність елементи колекцій.
SequenceEqual
SequenceEqual визначає чи усі елементи колекцій, що знаходяться на однаковій позиції, є рівними.
First / FirstOrDefault / Last / LastOrDefault
Дані оператори отримують предикат у якості аргументу. Оператор First повертає перший елемент колекції, що підпадає під умову. Якщо ж такого елемента не існує, викидається виключення. Оператор FirstOrDefault діє так само як First, але замість виключення повертає значення за умовчанням відповідного типу. Оператори Last та LastOrDefault виконують аналогічні операції, але з останніми підходящими елементами у колекції.
Single / SingleOrDefault
Оператор Single отримує предикат у якості аргументу та повертає єдиний елемент, що задовольняє предикат. Якщо ж таких елементів більше, ніж один, або немає взагалі, викидається виключення. При використанні SingleOrDefault, якщо жоден елемент у колекції не відповідає предикату, то замість виключення, повертається значення типу за умовчанням. В усіх інших випадках діє так само, як і Single.
ElementAt
Даний оператор повертає елемент, що має відповідний індекс у колекції.
Any / All
Оператор Any перевіряє чи хоча б один елемент у колекції відповідає предикату та повертає відповідне булеве значення. Виклик Any без предикату поверне істину, якщо в колекції є хоча б один елемент. Оператор All перевіряє чи відповідні предикату абсолютно всі елементи колекції.
Contains
Перевіряє чи колекція містить шуканий елемент.
Count
Підраховує кількість елементів у даній колекції. Перевантажений варіант приймає предикат у якості аргументу та рахує кількість елементів, що відповідають предикату.
Стандартне API операторів запитів також надає можливість конвертації колекцій до іншого типу:
IEnumerable<T>
.IQueryable<T>
.T[]
з вхідної колекції.List<T>
з вхідної колекції.Dictionary<K, T>
з вхідної колекції, з індексами типу K. Користувач передає у якості аргументу функцію проєкції, що повертає ключ для кожного об'єкту.Lookup<K, T>
з вхідної колекції, з індексами типу K
. Користувач передає у якості аргументу функцію проєкції, що повертає ключ для кожного об'єкту.IEnumerable
в узагальнену IEnumerable<T>
. В іншому випадку - конвертує узагальнену колекцію з одним параметром типу в колекцію з іншим параметром. Наприклад, IEnumerable<T>
в IEnumerable<R>
, приводячи кожен елемент типу T
до елементу типу R
. В разі, якщо хоча б один елемент колекції не може бути приведений до необхідного типу, викидається виключення.IEnumerable
в узагальнену IEnumerable<T>
. В іншому випадку - конвертує узагальнену колекцію з одним параметром типу в колекцію з іншим параметром. Наприклад, IEnumerable<T>
в IEnumerable<R>
, намагаючись привести кожен елемент типу T
до елементу типу R
. У результуючій колекції будуть знаходитися лише ті елементи, що були успішно сконвертовані.З появою LINQ, до мов програмування також був доданий синтаксичний цукор, щоб полегшити написання запитів. Дані розширення включають в себе такі:
var
. У VB9.0 для цього існує ключове слово Dim
. Такі об'єкти є строго типізованими.
Наприклад, у запиті, що повертає всі об'єкти зі значенням SomeProperty
меншим, ніж 10, типи змінних result та results виводяться компілятором, відповідно до сигнатур використаних методів:
var results = from c in SomeCollection
where c.SomeProperty < 10
select new {c.SomeProperty, c.OtherProperty};
foreach (var result in results)
{
Console.WriteLine(result);
}
Аналогічний запит також можна подати у наступному вигляді:
var results =
SomeCollection
.Where(c => c.SomeProperty < 10)
.Select(c => new {c.SomeProperty, c.OtherProperty});
results.ForEach(x => {Console.WriteLine(x.ToString());})
LINQ надає можливість працювати з різними джерелами даних. Для цього існують провайдери[2]. Будь-який розробник може написати власний провайдер для LINQ[3].
Провайдер LINQ to Objects використовується для колекцій, що знаходяться в пам'яті та застосовує для їх обробки локальний функціонал LINQ. Код, згенерований даним провайдером, реалізує архітектурний шаблон Sequence і дозволяє локально виконувати операції над колекціями IEnumerable<T>
. Поточна реалізація LINQ to Objects перевіряє які інтерфейси реалізовані у типі, що входить до колекції, щоб використати їх для швидкого виконання тих, чи інших запитів, якщо вони підтримуються типом під час виконання.
Провайдер LINQ to XML конвертує XML документ в колекцію об'єктів XElement
, над якою виконується запит, використовуючи локальний функціонал LINQ.
Провайдер LINQ to SQL дозволяє виконувати запити до бази даних Microsoft SQL Server. Оскільки дані, що зберігаються у SQL Server, зазвичай знаходяться на іншому сервері та SQL Server має свій власний функціонал по виконанню запитів, LINQ to SQL не використовує локальні можливості LINQ. Замість цього, вирази LINQ перекладаються у запити на мові SQL та відправляються до SQL Server, який обробляє ці запити та повертає результат, якщо необхідно. Однак, оскільки SQL Server є реляційною базою даних, а LINQ працює з об'єктами мови програмування, необхідно співставити відповідні дані. Для цього LINQ to SQL також реалізує спеціальний фреймворк. Співставлення відбувається, оголошуючи класи, які є аналогами таблиць у базі даних і містять в собі всі атрибути таблиці, або їх підмножину. Відповідність між полями класу та атрибутами у таблиці встановлюється через атрибути. Наприклад,
[Table(Name="Customers")]
public class Customer
{
[Column(IsPrimaryKey = true)]
public int CustID;
[Column]
public string CustName;
}
Даний клас співставляється з таблицею Customers
та містить в собі 2 поля, що відповідають двом колонкам таблиці.
Оскільки провайдер LINQ to SQL працює лише з SQL Server, для підтримки інших баз даних створено LINQ to DataSets. Даний провайдер використовує можливості ADO.NET для встановлення комунікації з базою даних. LINQ to DataSets виконує запити над даними, що містяться в наборах даних ADO.NET.
Починаючи з четвертої версії, .NET Framework включає в себе PLINQ (Parallel LINQ), що реалізує виконання LINQ запитів паралельно. Будь-який клас, що реалізує інтерфейс IEnumerable<T>
, може скористатися перевагами PLINQ, викликавши метод розширення AsParallel<T>(this IEnumerable<T>)
, що визначений у класі ParallelEnumerable простору імен System.Linq. PLINQ може виконувати частини запиту одночасно в різних потоках, що дозволяє отримати результат швидше.
Багато концепцій, які були введені в LINQ, спочатку були випробувані в науково-дослідному проекті Microsoft Cω, раніше відомому під кодовими іменами X# (X шарп) та Xen. Його перейменували на Cω після того як в нього було інтегровано іншу дослідницьку мову Polyphonic C# на основі числення об'єднань[en].
Cω намагається зробити сховища даних (такі як бази даних та XML документи) доступними з такою ж легкістю і безпекою типів як традиційні типи даних на зразок рядки та масиви. Багато цих ідей були успадковані від попереднього проекту інкубації в команді WebData XML під назвою X# та Xen. Cω також включає нові конструкції для підтримки конкурентного програмування; ці особливості в основному були отримані з попереднього проекту Polyphonic C#.[9]
Вперше доступні в 2004, функції Cω були використані Microsoft при створенні LINQ, випущеного в 2007 в .NET версії 3.5[10] Примітиви конкурентності також випущені в дещо модифікованій формі в бібліотеці Joins[en], для C# та інших .NET мов від Microsoft Research.[11]
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.