Знакомство с LINQ в Visual Basic

Встроенные в язык запросы (LINQ) добавляют возможности запросов в Visual Basic и обеспечивают простые и мощные возможности обработки всех видов данных. В отличие от отправки запроса для его обработки в базе данных или работы с разным синтаксисом запросов для каждого типа искомых данных, LINQ ввводит запросы как часть языка Visual Basic. В нем независимо от типа данных используется унифицированный синтаксис.

LINQ позволяет запрашивать данные из базы данных SQL Server, XML, массивов и коллекций в памяти, наборов данных ADO.NET или любого другого локального или удаленного источника данных, который поддерживает LINQ. Все это можно делать с помощью обычных элементов языка Visual Basic. Поскольку запросы пишутся на языке Visual Basic, результаты запроса возвращаются в виде строго типизированных объектов. Эти объекты поддерживают технологию IntelliSense, что позволяет писать код быстрее и перехватывать ошибки в запросах при компиляции, а не при выполнении. Запросы LINQ можно использовать в качестве источника дополнительных запросов для уточнения результатов. Они также могут быть связаны с элементами управления, чтобы пользователи легко могли просматривать и изменять результаты запроса.

Например, в следующем примере кода показан запрос LINQ, возвращающий список заказчиков из коллекции, и группирующий их по расположению.

Dim customers As List(Of Customer) = GetCustomerList()

Dim customersByCountry = From cust In customers 
                         Order By cust.Country, cust.City 
                         Group By CountryName = cust.Country 
                         Into RegionalCustomers = Group, Count() 
                         Order By CountryName

For Each country In customersByCountry
  Console.WriteLine(country.CountryName & 
                    " (" & country.Count & ")" & vbCrLf)

  For Each customer In country.RegionalCustomers
    Console.WriteLine(vbTab & customer.CompanyName & 
                      " (" & customer.City & ")")
  Next
Next

В этом разделе содержатся сведения о следующих областях:

  • Поставщики LINQ

  • Структура запроса LINQ

  • Операторы запросов LINQ в Visual Basic

  • Подключение к базе данных с помощью LINQ to SQL

  • Возможности Visual Basic, поддерживающего LINQ

  • Отложенное и немедленное выполнение запроса

  • XML в Visual Basic

  • Связанные ресурсы

  • Практические и пошаговые руководства

Поставщики LINQ

Поставщик LINQ сопоставляет запросы LINQ Visual Basic с запрашиваемым источником данных. При написании запроса LINQ поставщик принимает запрос и переводит его в команды, которые источник данных будет способен выполнить. Поставщик также преобразует данные из источника в объекты, составляющие результат запроса. Наконец, он преобразует объекты в данные при отправке обновлений на источник данных.

Visual Basic содержит следующие поставщики LINQ.

Поставщик

Описание

LINQ to Objects

Поставщик LINQ to Objects позволяет делать запросы к коллекциям и массивам, находящимся в памяти. Если объект поддерживает интерфейс IEnumerable или IEnumerable<T>, поставщик LINQ to Objects позволяет делать к объекту запросы.

Можно включить поставщик LINQ to Objects путем импорта пространства имен System.Linq, которое импортируется по умолчанию для всех проектов Visual Basic.

Дополнительные сведения о поставщике LINQ to Objects см. в разделе LINQ to Objects.

Запросы из LINQ в SQL

Поставщик LINQ to SQL позволяет запрашивать и изменять данные в базе данных SQL Server. Это упрощает сопоставление объектной модели приложения и таблиц и объектов в базе данных.

Visual Basic упрощает работу с LINQ to SQL включением реляционного конструктора объектов (O/R-конструктора). Этот конструктор используется для создания объектной модели в приложении, которая сопоставляется с объектами в базе данных. Реляционный конструктор объектов также предоставляет функциональные возможности для сопоставления хранимых процедур и функций с объектом DataContext, который управляет связью с базой данных и сохраняет состояние проверок на оптимистичный параллелизм.

Дополнительные сведения о поставщике LINQ to SQL см. в разделе LINQ to SQL. Дополнительные сведения о реляционном конструкторе объектов см. в разделе Реляционный конструктор объектов.

Запросы из LINQ в XML

Поставщик LINQ to XML позволяет запрашивать и изменять XML. Можно изменить XML в памяти, загрузить его из файла, сохранить в файл.

Кроме того, поставщик LINQ to XML разрешает использование литералов XML и свойств оси XML, что позволяет писать XML непосредственно в коде Visual Basic. Дополнительные сведения см. в разделе XML в Visual Basic.

LINQ to DataSet

Поставщик LINQ to DataSet позволяет запрашивать и обновлять данные в наборе данных ADO.NET. Можно добавить мощь LINQ в использующие наборы данных приложения, чтобы упростить и расширить возможности составления запросов к набору данных, его статистической обработки и обновления данных.

Дополнительные сведения см. в разделе LINQ to DataSet.

Структура запроса LINQ

Запрос LINQ, часто называемый как выражение запроса, состоит из комбинации предложений запросов, определяющих источники данных и переменные итерации для запроса. Выражение запроса может также включать инструкции сортировки, фильтрации, группировки и соединения, а также вычисления, применимые к источнику данных. Синтаксис выражения запроса напоминает синтаксис SQL; поэтому большая часть синтаксиса может показаться знакомой.

Выражение запроса начинается с предложения From. Это предложение указывает исходные данные для запроса и переменные, которые используются для обращения к каждому элементу источника данных по отдельности. Эти переменные называются переменные диапазона или итерационные переменные. Предложение From является обязательным для запроса, за исключением запросов Aggregate, в которых предложение From необязательно. После определения области и источника запроса в предложении From или Aggregate можно использовать любую комбинацию предложений запроса для его уточнения. Подробные сведения о предложениях запросов можно найти в теме "Операторы Visual Basic запросов LINQ" далее в этом разделе. Например, следующий запрос определяет исходную коллекцию данных клиента как переменную customers и как итерационная переменная cust.

Dim queryResults = From cust In customers 
                   Select cust.CompanyName

Данный пример сам по себе является допустимым запросом; однако запрос становится гораздо более мощным при добавлении нескольких предложений для уточнения результата. Например, можно добавить предложение Where для фильтрации результата по одному или нескольким значениям. Выражения запроса — это одна строка кода; можно просто добавлять дополнительные предложения в конец запроса. Можно разбить запрос на несколько строк текста для улучшения читаемости с помощью знака продолжения строки (_). В следующем примере кода показан пример запроса с предложением Where.

Dim queryResults = From cust In customers 
                   Where cust.Country = "USA"

Другое мощное предложение запроса — предложение Select. Оно позволяет возвращать только выбранные поля из источника данных. Запросы LINQ возвращают перечислимые коллекции строго типизированных объектов. Запрос может вернуть коллекцию как анонимных, так и именованных типов. Можно использовать предложение Select для получения только одного поля из источника данных. При этом тип возвращаемой коллекции — это тип этого поля. Можно также использовать предложение Select для получения нескольких полей из источника данных. При этом тип возвращаемой коллекции — это новый анонимный тип. Можно также сопоставить возвращенные запросом поля с полями указанного именованного типа. В следующем примере кода показано выражение запроса, возвращающее коллекцию анонимных типов, члены которых заполняются данными из выбранных полей источника данных.

Dim queryResults = From cust In customers 
               Where cust.Country = "USA" 
               Select cust.CompanyName, cust.Country

Запросы LINQ могут также использоваться для объединения нескольких источников данных и получения единого результата. Это можно сделать с помощью одного или нескольких предложений From или с помощью предложений Join или Group Join. В следующем примере кода показано выражение запроса, объединяющее данные клиентов и заказов и возвращающее коллекцию анонимных типов, содержащих их данные.

Dim queryResults = From cust In customers, ord In orders 
                   Where cust.CustomerID = ord.CustomerID 
                   Select cust, ord

Можно использовать предложение Group Join для получения иерархического результата запроса, содержащего коллекцию объектов клиента. Каждый объект клиента имеет свойство, содержащее коллекцию всех заказов этого клиента. В следующем примере показано выражение запроса, объединяющее данные клиентов и заказов как иерархический результат и возвращающее коллекцию анонимных типов. Запрос возвращает тип, у которого есть свойство CustomerOrders, содержащее коллекцию данных заказов клиента. У него также есть свойство OrderTotal, которое содержит общую сумму всех заказов этого клиента. (Этот запрос эквивалентен LEFT OUTER JOIN.)

Dim queryResults = From cust In customers 
                   Group Join ord In orders On 
                     cust.CustomerID Equals ord.CustomerID 
                     Into CustomerOrders = Group, 
                          OrderTotal = Sum(ord.Total) 
                   Select cust.CompanyName, cust.CustomerID, 
                          CustomerOrders, OrderTotal

Имеется несколько дополнительных операторов запросов LINQ, которые можно использовать для создания мощных выражений запросов. В следующей теме этого раздела описываются различные предложения запросов, которые можно использовать в выражениях запросов. Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).

Операторы запросов LINQ в Visual Basic

Классы в поддерживающих запросы LINQ пространствах имен (в частности, System.Linq) содержат методы создания и уточнения запросов. Их можно использовать исходя из нужд приложения. Visual Basic содержит ключевые слова для наиболее общих предложений запросов, как описано в следующей таблице.

Термин

Определение

Предложение From (Visual Basic)

Предложение From или Aggregate требуется для начала запроса. Предложение From определяет коллекцию источника и переменную итерации для запроса. Пример.

Предложение Select (Visual Basic)

Необязательный. Объявляет набор переменных итераций для запроса. Пример.

Если не указано предложение Select, то переменные итераций для запроса — это переменные итераций, указанные в предложении From или Aggregate.

Предложение Where (Visual Basic)

Необязательный. Устанавливает условия фильтрации для запроса. Пример.

Предложение Order By (Visual Basic)

Необязательный. Устанавливает порядок сортировки для столбцов в запросе. Пример.

Предложение Join (Visual Basic)

Необязательный. Объединяет две коллекции в одну. Пример.

Предложение Group By (Visual Basic)

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

Предложение Group Join (Visual Basic)

Необязательный. Объединяет две коллекции в одну иерархическую. Пример.

Предложение Aggregate (Visual Basic)

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

Предложение Aggregate можно также использовать для изменения запроса. Например, можно использовать предложение Aggregate для выполнения вычислений с результатом связанного запроса.

Предложение Let (Visual Basic)

Необязательный. Вычисляет значение и присваивает его новой переменной в запросе. Пример.

Предложение Distinct (Visual Basic)

Необязательный. Ограничивает значения текущей переменной итерации, чтобы исключить повторяющиеся значения в результатах запроса. Пример.

Предложение Skip (Visual Basic)

Необязательный. Пропускает заданное число элементов в коллекции и возвращает остальные элементы. Пример.

Предложение Skip While (Visual Basic)

Необязательный. Пропускает элементы в коллекции, пока заданное условие является true и затем возвращает оставшиеся элементы. Пример.

Предложение Take (Visual Basic)

Необязательный. Возвращает указанное число последовательных элементов от начала коллекции. Пример.

Предложение Take While (Visual Basic)

Необязательный. Включает элементы в коллекцию, пока заданное условие является true, и затем пропускает оставшиеся элементы. Пример.

Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).

Можно использовать дополнительные возможности запросов LINQ путем обращения к членам перечислимых и доступных для запроса типов, предоставляемых LINQ. Можно использовать эти дополнительные возможности, вызвав конкретный оператор запроса на результате выражения запроса. Например, код следующего примера использует метод Union для объединения результатов двух запросов в один. Он использует метод ToList<TSource> для возвращения результата запроса в виде универсального списка.

Public Function GetAllCustomers() As List(Of Customer)
  Dim customers1 = From cust In domesticCustomers
  Dim customers2 = From cust In internationalCustomers

  Dim customerList = customers1.Union(customers2)

  Return customerList.ToList()
End Function

Сведения о дополнительных возможностях LINQ см. в Общие сведения о стандартных операторах запроса.

Подключение к базе данных с помощью LINQ to SQL

В Visual Basic идентификация объектов базы данных SQL Server (таблицы, представления, хранимые процедуры), к которым нужен доступ, происходит с помощью файла LINQ to SQL. Файл LINQ to SQL имеет расширение .dbml.

При наличии допустимого подключения к базе данных SQL Server можно добавить в проект шаблон элемента Классы LINQ to SQL. Это даст возможность отобразить реляционный конструктор объектов (O/R-конструктор). O/R-конструктор дает возможность перетаскивать элементы, к которым нужен доступ в коде, из обозревателя серверов / обозревателя баз данных на поверхность конструктора. Файл LINQ to SQL добавляет объект DataContext в проект. Этот объект включает в себя свойства и коллекции для таблиц и представлений, к которым нужен доступ, а также необходимые методы для хранимых процедур. После сохранения изменений в файле LINQ to SQL (.dbml) можно получить доступ к этим объектам в коде, обратившись к определенному O/R-конструктором объекту DataContext. Объекту DataContext для проекта присваивается имя на основе имени файла LINQ to SQL. Например, файл LINQ to SQL с именем Northwind.dbml создаст объект DataContext с именем NorthwindDataContext.

Примеры с пошаговыми инструкциями см. в разделах Практическое руководство. Выполнение запросов к базе данных с помощью LINQ (Visual Basic) и Практическое руководство. Вызов хранимой процедуры с помощью LINQ (Visual Basic).

Возможности Visual Basic, поддерживающего LINQ

Visual Basic имеет другие важные возможности, упрощающие использование LINQ и уменьшающие требуемый для написания запросов объем кода. Ниже перечислены некоторые из этих методов.

  • Анонимные типы, позволяющие создать новый тип, основанный на результатах запроса.

  • Неявно типизированные переменные, позволяющие отложить указание типа и позволить компилятору передавать тип, основанный на результатах запроса.

  • Методы расширения, позволяющие расширять существующий тип своими собственными методами без изменения самого типа.

Дополнительные сведения см. в разделе Возможности Visual Basic, поддерживающие LINQ.

Отложенное и немедленное выполнение запроса

Выполнение запроса разделено с его созданием. После создания запроса его выполнение инициируется отдельным механизмом. Запрос может выполняться по мере его определения (немедленное выполнение), или его определение может быть сохранено и запрос может быть выполнен позднее (отложенное выполнение).

По умолчанию при создании запроса он не выполняется. Вместо этого определение запроса хранится в переменной, используемой для ссылки на результаты запроса. Если доступ к переменной результата запроса выполняется позже в коде, например в цикле For…Next, запрос выполняется. Такой процесс называется отложенным выполнением.

Запросы могут также выполняться при их определении. Это называется немедленное выполнение. Можно инициировать немедленное выполнение, применив метод, требующий доступа к отдельным элементам результата запроса. Это может быть результатом использования агрегатных функций, таких как Count, Sum, Average, Min или Max. Дополнительные сведения об агрегатных функциях см. в разделе Предложение Aggregate (Visual Basic).

Использование методов ToList или ToArray также приведет к немедленному выполнению. Это может быть полезно, если надо выполнить запрос немедленно и занести результаты в кэш. Дополнительные сведения об этих методах см. в разделе Преобразование типов данных.

Дополнительные сведения о выполнении запроса см. в разделе Написание первого запроса LINQ (Visual Basic).

XML в Visual Basic

Возможности XML в Visual Basic включают литералы XML и свойства оси XML, что позволяет легко создавать, запрашивать, изменять и получать доступ к XML в коде. Литералы XML позволяют писать XML непосредственно в коде. Компилятор Visual Basic обрабатывает XML как объект данных первого класса.

В следующем примере показано, как создать элемент XML, получить доступ к его дочерним элементам и атрибутам и делать запросы к содержимому элемента с помощью LINQ.

' Place Imports statements at the top of your program.  
Imports <xmlns:ns="http://SomeNamespace">

Module Sample1

    Sub SampleTransform()

        ' Create test by using a global XML namespace prefix. 

        Dim contact = 
            <ns:contact>
                <ns:name>Patrick Hines</ns:name>
                <ns:phone ns:type="home">206-555-0144</ns:phone>
                <ns:phone ns:type="work">425-555-0145</ns:phone>
            </ns:contact>

        Dim phoneTypes = 
          <phoneTypes>
              <%= From phone In contact.<ns:phone> 
                  Select <type><%= phone.@ns:type %></type> 
              %>
          </phoneTypes>

        Console.WriteLine(phoneTypes)
    End Sub

End Module

Дополнительные сведения см. в разделе XML в Visual Basic.

Связанные ресурсы

Раздел

Описание

XML в Visual Basic

Описание возможностей XML в Visual Basic, к которым можно делать запросы и которые позволяют включать XML как объекты данных первого класса в коде Visual Basic.

Запросы (Visual Basic)

Содержит справочные сведения о предложениях запросов, которые доступны в Visual Basic.

LINQ

Содержит общие сведения, рекомендации по программированию и примеры для LINQ.

LINQ to SQL

Содержит общие сведения, рекомендации по программированию и примеры для LINQ to SQL.

LINQ to Objects

Содержит общие сведения, рекомендации по программированию и примеры для LINQ to Objects.

LINQ to ADO.NET (Страница портала)

Содержит ссылки на общие сведения, рекомендации по программированию и примеры для LINQ ADO.NET.

LINQ to XML

Содержит общие сведения, рекомендации по программированию и примеры для LINQ to XML.

Практические и пошаговые руководства

Практическое руководство. Выполнение запросов к базе данных с помощью LINQ (Visual Basic)

Практическое руководство. Вызов хранимой процедуры с помощью LINQ (Visual Basic)

Практическое руководство. Изменение данных в базе данных с помощью LINQ (Visual Basic)

Практическое руководство. Объединение данных с помощью LINQ с использованием соединений (Visual Basic)

Практическое руководство. Сортировка результатов запроса с помощью LINQ (Visual Basic)

Практическое руководство. Фильтрование результатов запроса с помощью LINQ (Visual Basic)

Практическое руководство. Выполнение над данными функций Count, Sum и Average с помощью LINQ (Visual Basic)

Практическое руководство. Поиск минимального или максимального значения в результатах запроса с помощью LINQ (Visual Basic)

Пошаговое руководство. Создание классов LINQ to SQL (реляционный конструктор объектов)

Как назначить хранимые процедуры для выполнения обновлений, вставок и удалений (реляционный конструктор объектов)

Главы в популярных книгах

Chapter 17: LINQ в книге Programming Visual Basic 2008

См. также

Задачи

Примеры LINQ

Основные понятия

Общие сведения о LINQ to XML в Visual Basic

Общие сведения о LINQ to DataSet

Методы DataContext (реляционный конструктор объектов)

Другие ресурсы

LINQ

LINQ to SQL

Реляционный конструктор объектов