Jump to content

Языковой интегрированный запрос

(Перенаправлено с Polyphonic C Sharp )
Языковой интегрированный запрос
Разработано Корпорация Майкрософт
Разработчик Корпорация Майкрософт
Дисциплина набора текста Строго типизированный
Веб-сайт https://learn.microsoft.com/en-us/dotnet/standard/linq/
Основные реализации
Языки .NET ( C# , F# , VB.NET )
Под влиянием
SQL , Хаскель

Language Integrated Query ( LINQ , произносится как «ссылка») — это компонент Microsoft .NET Framework данных , который добавляет собственные возможности запроса к языкам .NET , первоначально выпущенный как основная часть .NET Framework 3.5 в 2007 году.

LINQ расширяет язык за счет добавления выражений запросов , которые аналогичны операторам SQL и могут использоваться для удобного извлечения и обработки данных из массивов , перечислимых классов , XML- документов, реляционных баз данных и сторонних источников данных. Другие применения, в которых выражения запросов используются в качестве общей основы для читаемого составления произвольных вычислений, включают создание обработчиков событий. [1] или монадические парсеры . [2] Он также определяет набор имен методов (называемых стандартными операторами запроса или стандартными операторами последовательности ), а также правила перевода, используемые компилятором для перевода выражений синтаксиса запроса в выражения с использованием свободного стиля (так называемый синтаксис метода в Microsoft) с этими именами методов. , лямбда-выражения и анонимные типы .

Существуют порты LINQ для PHP ( PHPLinq ), JavaScript ( linq.js ), TypeScript ( linq.ts ) и ActionScript ( ActionLinq ), хотя ни один из них не является строго эквивалентным LINQ в языках C#, F# и VB.NET, вдохновленных .NET. (где он является частью языка, а не внешней библиотекой, и часто удовлетворяет более широкий спектр потребностей). [ нужна ссылка ]

Архитектура LINQ в .NET Framework

[ редактировать ]

Стандартный API оператора запроса

[ редактировать ]

Далее описания операторов основаны на применении работы с коллекциями. Многие операторы принимают в качестве аргументов другие функции. Эти функции могут быть предоставлены в форме именованного метода или анонимной функции.

Набор операторов запроса , определенный LINQ, предоставляется пользователю как API стандартного оператора запроса (SQO) . Операторы запроса, поддерживаемые API: [3]

Выбирать

Оператор Select выполняет проекцию коллекции для выбора. интересные аспекты стихий. Пользователь предоставляет произвольную функцию в форме именованного или лямбда-выражения , которая проецирует элементы данных. Функция передается оператору в качестве делегата .

Где

Оператор Where позволяет определить набор правил предикатов, которые оцениваются для каждого объекта в коллекции, а объекты, не соответствующие правилу, отфильтровываются. Предикат передается оператору в качестве делегата.

ВыбратьМного

Для предоставленного пользователем сопоставления элементов коллекции с коллекциями семантически выполняются два шага. Во-первых, каждый элемент сопоставляется с соответствующей коллекцией. Во-вторых, результат первого шага выравнивается на один уровень. Примечание. Select и Where реализуются с помощью SelectMany, если доступны одноэлементные и пустые коллекции. Упомянутые выше правила трансляции по-прежнему обязывают поставщика LINQ предоставлять два других оператора.

Сумма/Мин/Макс/Среднее

Эти операторы опционально принимают функцию, которая извлекает определенное числовое значение из каждого элемента коллекции и использует его для нахождения суммы, минимума, максимума или среднего значения всех элементов коллекции соответственно. Перегруженные версии не выполняют никаких функций и действуют так, как если бы идентификатор задавался как лямбда.

Совокупный

Обобщенная Сумма/Мин/Макс. Этот оператор принимает функцию, которая определяет, как два значения объединяются для формирования промежуточного или окончательного результата. При желании можно указать начальное значение, что позволит выбрать произвольный тип результата агрегирования. Кроме того, может быть предоставлена ​​функция финализации, переводящая результат агрегирования в другое значение.

Присоединиться / Присоединиться к группе
Оператор Join выполняет внутреннее соединение двух коллекций на основе совпадения ключей для объектов в каждой коллекции. В качестве делегатов он принимает две функции, по одной для каждой коллекции, которые он выполняет для каждого объекта в коллекции, чтобы извлечь ключ из объекта. Также требуется еще один делегат, в котором пользователь указывает, какие элементы данных из двух совпадающих элементов должны использоваться для создания результирующего объекта. Оператор GroupJoin выполняет объединение группы . Как и оператор Select, результаты соединения представляют собой экземпляры другого класса со всеми элементами данных обоих типов исходных объектов или их подмножества.
Возьмите/Возьмите Пока
Оператор Take выбирает первые n объектов из коллекции, а оператор TakeWhile, принимающий предикат, выбирает те объекты, которые соответствуют предикату (останавливаясь на первом объекте, который ему не соответствует).
Пропустить / Пропустить пока
Операторы Skip и SkipWhile дополняют операторы Take и TakeWhile — они пропускают первые n объектов из коллекции или те объекты, которые соответствуют предикату (в случае SkipWhile).
Тип
Оператор OfType используется для выбора элементов определенного типа.
Конкат
Оператор Concat объединяет две коллекции.
ЗаказатьПо/ЗатемПо
Оператор OrderBy используется для указания первичного порядка сортировки элементов коллекции по некоторому ключу. По умолчанию порядок упорядочен по возрастанию. Чтобы изменить порядок, OrderByDescending необходимо использовать оператор . thenBy и thenByDescending задают последующий порядок элементов. Функция для извлечения значения ключа из объекта указывается пользователем в качестве делегата.
Обеспечить регресс
Оператор Reverse обращает коллекцию.
ГруппаПо
Оператор GroupBy принимает функцию, которая извлекает значение ключа и возвращает коллекцию IGrouping<Key, Values> объекты для каждого отдельного значения ключа. IGrouping Затем объекты можно использовать для перечисления всех объектов для определенного значения ключа.
Отчетливый
Оператор Distinct удаляет повторяющиеся экземпляры объекта из коллекции. Перегрузка оператора принимает объект сравнения равенства, который определяет критерии отличимости.
Объединение / Пересечение / Исключение
Эти операторы используются для выполнения операций объединения , пересечения и разности двух последовательностей соответственно. Каждый из них имеет перегрузку, которая принимает объект сравнения элементов на равенство, определяющий критерии равенства элементов.
ПоследовательностьРавно
Оператор SequenceEqual определяет, равны ли все элементы в двух коллекциях и находятся ли они в одном и том же порядке.
Первый/FirstOrDefault/Последний/LastOrDefault
Эти операторы принимают предикат. Оператор First возвращает первый элемент, для которого предикат возвращает true, или, если ничего не соответствует, выдает исключение. Оператор FirstOrDefault аналогичен оператору First, за исключением того, что он возвращает значение по умолчанию для типа элемента (обычно нулевую ссылку) в случае, если ничто не соответствует предикату. Последний оператор извлекает последний элемент, соответствующий предикату, или выдает исключение, если ничего не соответствует. LastOrDefault возвращает значение элемента по умолчанию, если ничего не соответствует.
Одинокий
Оператор Single принимает предикат и возвращает элемент, соответствующий предикату. Исключение выдается, если ни один или более одного элемента не соответствует предикату.
ОдиночныйОрПо умолчанию
Оператор SingleOrDefault принимает предикат и возвращает элемент, соответствующий предикату. Если предикату соответствует более одного элемента, выдается исключение. Если ни один элемент не соответствует предикату, возвращается значение по умолчанию.
элемент
Оператор ElementAt извлекает элемент по заданному индексу в коллекции.
Любой/Все
Оператор Any проверяет, есть ли в коллекции элементы, соответствующие предикату. Он не выбирает элемент, но возвращает true, если соответствует хотя бы один элемент. Вызов Any без предиката возвращает true, если коллекция не пуста. Оператор All возвращает true, если все элементы соответствуют предикату.
Содержит
Оператор Содержит проверяет, содержит ли коллекция заданный элемент.
Считать
Оператор Count подсчитывает количество элементов в данной коллекции. Перегрузка, принимающая предикат, подсчитывает количество элементов, соответствующих предикату.

API стандартного оператора запроса также определяет определенные операторы, которые преобразуют коллекцию в другой тип: [3]

  • AsEnumerable: Статически типизирует коллекцию как IEnumerable<T>. [4]
  • AsQueryable: Статически типизирует коллекцию как IQueryable<T>.
  • ToArray: создает массив. T[] из коллекции.
  • ToList: Создает List<T> из коллекции.
  • ToDictionary: Создает Dictionary<K, T> из коллекции, индексированной ключом K. Предоставленная пользователем функция проецирования извлекает ключ из каждого элемента.
  • ToLookup: Создает Lookup<K, T> из коллекции, индексированной ключом K. Предоставленная пользователем функция проецирования извлекает ключ из каждого элемента.
  • Cast: преобразует неуниверсальный IEnumerable сбор в один из IEnumerable<T> путем приведения каждого элемента к типу T. Альтернативно преобразует общий IEnumerable<T> к другому общему IEnumerable<R> путем приведения каждого элемента из типа T печатать R. Вызывает исключение в любом элементе, который невозможно привести к указанному типу.
  • OfType: преобразует необобщенный IEnumerable сбор в один из IEnumerable<T>. Альтернативно преобразует общий IEnumerable<T> к другому общему IEnumerable<R> пытаясь привести каждый элемент из типа T печатать R. В обоих случаях включается только подмножество элементов, успешно приведенных к целевому типу. Никаких исключений не создается.

Языковые расширения

[ редактировать ]

Хотя LINQ в основном реализован как библиотека для .NET Framework 3.5, он также определяет дополнительные языковые расширения, которые делают запросы первоклассными языковыми конструкциями и предоставляют синтаксический сахар для написания запросов. Эти языковые расширения изначально были реализованы в C# 3.0. [5] : 75  ВБ 9.0 , Ф# [6] и Oxygene , а другие языки, такие как Nemerle, объявили о предварительной поддержке. Языковые расширения включают в себя: [7]

  • Синтаксис запроса: язык может свободно выбирать синтаксис запроса, который он распознает изначально. Эти ключевые слова языка должны быть преобразованы компилятором в соответствующие вызовы методов LINQ.
  • Неявно типизированные переменные. Это усовершенствование позволяет объявлять переменные без указания их типов. Языки C# 3.0 [5] : 367  и Oxygene объявляют их с помощью var ключевое слово. В VB9.0 Dim Ключевое слово без объявления типа выполняет то же самое. Такие объекты по-прежнему строго типизированы ; для этих объектов компилятор определяет типы переменных посредством вывода типа , что позволяет указывать и определять результаты запросов без объявления типа промежуточных переменных.
  • Анонимные типы . Анонимные типы позволяют компилятору выводить классы, содержащие только объявления членов данных. Это полезно для операторов Select и Join, типы результатов которых могут отличаться от типов исходных объектов. Компилятор использует вывод типа для определения полей, содержащихся в классах, и генерирует средства доступа и мутаторы для этих полей.
  • Инициализатор объекта : Инициализаторы объекта позволяют создавать и инициализировать объект в одной области, как это требуется для операторов Select и Join.
  • Лямбда-выражения . Лямбда-выражения позволяют записывать предикаты и другие функции проекции встроенными с кратким синтаксисом и поддерживают полное лексическое замыкание. Они фиксируются в параметрах в виде делегатов или деревьев выражений в зависимости от поставщика запросов.

Например, в запросе на выбор всех объектов в коллекции с помощью SomeProperty менее 10,

var results =  from c in SomeCollection
               where c.SomeProperty < 10
               select new {c.SomeProperty, c.OtherProperty};

foreach (var result in results)
{
        Console.WriteLine(result);
}

типы переменных result , c и results выводятся компилятором в соответствии с сигнатурами используемых в конечном итоге методов. В основе выбора методов лежит результат перевода запроса без выражений.

var results =
     SomeCollection
        .Where(c => c.SomeProperty < 10)
        .Select(c => new {c.SomeProperty, c.OtherProperty});

results.ForEach(x => {Console.WriteLine(x.ToString());})

Поставщики LINQ

[ редактировать ]

Спецификация C#3.0 определяет шаблон выражения запроса вместе с правилами перевода из выражения LINQ в выражение в подмножестве C# 3.0 без выражений LINQ. Определенный таким образом перевод на самом деле не является типизированным, что, помимо того, что лямбда-выражения интерпретируются как делегаты или деревья выражений, обеспечивает большую степень гибкости для библиотек, желающих представить части своего интерфейса в виде предложений выражений LINQ. Например, LINQ to Objects работает на IEnumerable<T>s и с делегатами, тогда как LINQ to SQL использует деревья выражений.

Деревья выражений лежат в основе механизма расширяемости LINQ, с помощью которого LINQ можно адаптировать для многих источников данных. Деревья выражений передаются поставщикам LINQ, которые представляют собой реализации для конкретных источников данных, которые адаптируют запросы LINQ для использования с источником данных. Если они того пожелают, поставщики LINQ анализируют деревья выражений, содержащиеся в запросе, чтобы сгенерировать важные фрагменты, необходимые для выполнения запроса. Это могут быть фрагменты SQL или любое другое совершенно другое представление кода в качестве дополнительных данных, которыми можно манипулировать. LINQ поставляется с поставщиками LINQ для коллекций объектов в памяти, баз данных Microsoft SQL Server , наборов данных ADO.NET и документов XML. Эти разные поставщики определяют разные варианты LINQ:

LINQ для объектов

[ редактировать ]

Поставщик LINQ to Objects используется для коллекций в памяти с использованием локального механизма выполнения запросов LINQ. Код, сгенерированный этим поставщиком, относится к реализации стандартных операторов запроса, как определено в Sequence шаблон и позволяет IEnumerable<T> коллекции, которые будут запрашиваться локально. Текущая реализация LINQ to Objects выполняет проверки реализации интерфейса, чтобы обеспечить быструю проверку членства, подсчет и операции индексированного поиска, если они поддерживаются типом среды выполнения IEnumerable. [8] [9] [10]

LINQ to XML (ранее назывался XLINQ)

[ редактировать ]

Поставщик LINQ to XML преобразует XML-документ в коллекцию XElement объекты, которые затем запрашиваются с использованием локального механизма выполнения, предоставляемого как часть реализации стандартного оператора запроса. [11]

LINQ to SQL (ранее называвшийся DLINQ)

[ редактировать ]

Поставщик LINQ to SQL позволяет использовать LINQ для запроса баз данных Microsoft SQL Server , включая базы данных SQL Server Compact . Поскольку данные SQL Server могут находиться на удаленном сервере и поскольку SQL Server имеет собственный механизм запросов, LINQ to SQL не использует механизм запросов LINQ. Вместо этого он преобразует запрос LINQ в запрос SQL , который затем отправляется на сервер SQL для обработки. [12] Однако, поскольку SQL Server хранит данные как реляционные данные , а LINQ работает с данными, инкапсулированными в объекты, эти два представления необходимо сопоставить друг с другом. По этой причине LINQ to SQL также определяет структуру сопоставления. Сопоставление осуществляется путем определения классов, которые соответствуют таблицам в базе данных и содержат все или подмножество столбцов таблицы в качестве членов данных. [13] Соответствие, а также другие атрибуты реляционной модели , такие как первичные ключи , указываются с помощью атрибутов, определенных LINQ to SQL . Например,

[Table(Name="Customers")]
public class Customer
{
     [Column(IsPrimaryKey = true)]
     public int CustID;

     [Column]
     public string CustName;
}

Это определение класса отображается в таблицу с именем Customers и два элемента данных соответствуют двум столбцам. Классы должны быть определены до того, как можно будет использовать LINQ to SQL. Visual Studio 2008 включает в себя конструктор сопоставлений, который можно использовать для создания сопоставлений между схемами данных в объекте, а также в реляционном домене. Он может автоматически создавать соответствующие классы из схемы базы данных , а также разрешать ручное редактирование для создания другого представления, используя только подмножество таблиц или столбцов в таблице. [13]

Отображение реализуется DataContext который передает строку подключения к серверу и может использоваться для создания Table<T> где T — тип, которому будет сопоставлена ​​таблица базы данных. Table<T> инкапсулирует данные в таблице и реализует IQueryable<T> интерфейс, так что создается дерево выражений, которое обрабатывает поставщик LINQ to SQL. Он преобразует запрос в T-SQL и получает набор результатов с сервера базы данных. Поскольку обработка происходит на сервере базы данных, локальные методы, которые не определены как часть лямбда-выражений, представляющих предикаты, использовать нельзя. Однако он может использовать хранимые процедуры на сервере. Любые изменения в наборе результатов отслеживаются и могут быть отправлены обратно на сервер базы данных. [13]

LINQ для наборов данных

[ редактировать ]

Поскольку поставщик LINQ to SQL (выше) работает только с базами данных Microsoft SQL Server , для поддержки любой универсальной базы данных LINQ также включает LINQ to DataSets. Он использует ADO.NET для управления связью с базой данных. Как только данные попадают в наборы данных ADO.NET, LINQ to DataSets выполняет запросы к этим наборам данных. [14]

Производительность

[ редактировать ]

Непрофессиональные пользователи могут столкнуться с тонкостями функций и синтаксиса LINQ to Objects . Наивные шаблоны реализации LINQ могут привести к катастрофическому снижению производительности. [15] [16]

Производительность LINQ to XML и LINQ to SQL по сравнению с ADO.NET зависит от варианта использования. [17] [18]

Версия 4 платформы .NET включает PLINQ или Parallel LINQ , механизм параллельного выполнения запросов LINQ. Он определяет ParallelQuery<T> сорт. Любая реализация IEnumerable<T> интерфейс может воспользоваться преимуществами механизма PLINQ, вызвав метод AsParallel<T>(this IEnumerable<T>) метод расширения, определенный классом ParallelEnumerable в пространстве имен System.Linq платформы .NET. [19] Механизм PLINQ может выполнять части запроса одновременно в нескольких потоках, обеспечивая более быстрые результаты. [20]

Языки-предшественники

[ редактировать ]

Многие концепции, представленные LINQ, изначально были протестированы в рамках исследовательского проекта Microsoft , ранее известного под кодовыми названиями X# (X Sharp) и Xen . Он был переименован в Cω после того, как в него был интегрирован Polyphonic C# , другой исследовательский язык, основанный на исчислении соединений .

Cω пытается сделать хранилища данных (такие как базы данных и XML- документы) доступными с той же легкостью и безопасностью типов , что и традиционные типы, такие как строки и массивы . Многие из этих идей были унаследованы от более раннего инкубационного проекта группы WebData XML под названием X# и Xen. Cω также включает новые конструкции для поддержки параллельного программирования ; эти функции во многом были заимствованы из более раннего проекта Polyphonic C#. [21]

Впервые доступные в 2004 году в качестве предварительной версии компилятора, функции Cω впоследствии были использованы Microsoft при создании функций LINQ, выпущенных в 2007 году в .NET версии 3.5. [22] Конструкции параллелизма также были выпущены в слегка измененной форме в виде библиотеки под названием Joins Concurrency Library для C# и других языков .NET компанией Microsoft Research . [23]

См. также

[ редактировать ]
  1. ^ «Рамка Rx» .
  2. ^ «Монадические парсеры-комбинаторы с использованием C#3» . Проверено 21 ноября 2009 г.
  3. ^ Перейти обратно: а б «Стандартные операторы запросов» . Майкрософт . Проверено 30 ноября 2007 г.
  4. ^ «Перечислимый класс» . мсдн . Майкрософт . Проверено 15 февраля 2014 г.
  5. ^ Перейти обратно: а б Скит, Джон. C# в глубине . Мэннинг. ISBN  978-1617294532 .
  6. ^ «Выражения запроса (F#)» . Документы Майкрософт . Проверено 19 декабря 2012 г.
  7. ^ «LINQ-фреймворк» . Проверено 30 ноября 2007 г.
  8. ^ "Перечисляемый.ЭлементАт" . Проверено 7 мая 2014 г.
  9. ^ «Перечисляемый.Содержит» . Проверено 7 мая 2014 г.
  10. ^ «Перечисляемый.Количество» . Проверено 7 мая 2014 г.
  11. ^ «Интегрированный в язык .NET запрос к XML-данным» . Проверено 30 ноября 2007 г.
  12. ^ «LINQ to SQL» . Архивировано из оригинала 25 января 2013 г. Проверено 30 ноября 2007 г.
  13. ^ Перейти обратно: а б с «LINQ to SQL: интегрированный в язык .NET запрос реляционных данных» . Проверено 30 ноября 2007 г.
  14. ^ «LINQ для наборов данных» . Архивировано из оригинала 25 января 2013 г. Проверено 30 ноября 2007 г.
  15. ^ Видер, Гай (21 декабря 2007 г.). «Тест производительности LINQ: мой первый проект Visual Studio 2008» . Проверено 8 февраля 2009 г.
  16. ^ Парсонс, Джаред (2008). «Повышение производительности запросов LINQ» . Сеть разработчиков Microsoft . Проверено 19 марта 2014 г. Хотя это правда, что LINQ является мощным и очень эффективным инструментом, большие наборы данных все равно могут вызывать неожиданные проблемы с производительностью.
  17. ^ Альва, Хайме (6 августа 2010 г.). «Потенциальные проблемы с производительностью при повторной компиляции скомпилированных запросов LINQ» . Сеть разработчиков Microsoft . Проверено 19 марта 2014 г. При многократном вызове запроса с помощью Entity Framework рекомендуется использовать скомпилированные запросы LINQ. Компиляция запроса приводит к снижению производительности при первом использовании запроса, но последующие вызовы выполняются намного быстрее.
  18. ^ Кшитидж, Пандей (25 мая 2008 г.). «Сравнение производительности LinQ с SQL, ADO, C#» . Проверено 8 февраля 2009 г.
  19. ^ «Класс ParallelEnumerable» . Проверено 7 мая 2014 г.
  20. ^ «Программирование в эпоху параллелизма: параллельное программирование с PFX» . Проверено 16 октября 2007 г.
  21. ^ Эйхерт, Стив; Вули, Джеймс Б.; Маргери, Фабрис (2008). LINQ в действии . Мэннинг. стр. 56-57 (как сообщается в ссылке поиска Google Книги - в книге нет номеров страниц). ISBN  9781638354628 .
  22. ^ Концепции языка C# 3.0 | Статьи | TomasP.Net. Архивировано 12 февраля 2007 г. в Wayback Machine.
  23. ^ «Библиотека параллелизма объединений» . Проверено 8 июня 2007 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 8c80ef50994515a7e99775a1925ec6b9__1699206420
URL1:https://arc.ask3.ru/arc/aa/8c/b9/8c80ef50994515a7e99775a1925ec6b9.html
Заголовок, (Title) документа по адресу, URL1:
Language Integrated Query - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)