Знакомство с LINQ в Visual Basic
Встроенные в язык запросы (LINQ) добавляют возможности запросов в Visual Basic и обеспечивают простые и мощные возможности обработки всех видов данных. В отличие от отправки запроса для его обработки в базе данных или работы с разным синтаксисом запросов для каждого типа искомых данных, LINQ ввводит запросы как часть языка Visual Basic. В нем независимо от типа данных используется унифицированный синтаксис.
LINQ позволяет запрашивать данные из базы данных SQL Server, XML, массивов и коллекций в памяти, наборов данных ADO.NET или любого другого локального или удаленного источника данных, который поддерживает LINQ. Все это можно делать с помощью обычных элементов языка Visual Basic. Поскольку запросы пишутся на языке Visual Basic, результаты запроса возвращаются в виде строго типизированных объектов. Эти объекты поддерживают технологию IntelliSense, что позволяет писать код быстрее и перехватывать ошибки в запросах при компиляции, а не при выполнении. Запросы LINQ можно использовать в качестве источника дополнительных запросов для уточнения результатов. Они также могут быть связаны с элементами управления, чтобы пользователи легко могли просматривать и изменять результаты запроса.
Например, в следующем примере кода показан запрос LINQ, возвращающий список заказчиков из коллекции, и группирующий их по расположению.
' Obtain a list of customers.
Dim customers As List(Of Customer) = GetCustomers()
' Return customers that are grouped based on country.
Dim countries = From cust In customers
Order By cust.Country, cust.City
Group By CountryName = cust.Country
Into CustomersInCountry = Group, Count()
Order By CountryName
' Output the results.
For Each country In countries
Debug.WriteLine(country.CountryName & " count=" & country.Count)
For Each customer In country.CustomersInCountry
Debug.WriteLine(" " & customer.CompanyName & " " & customer.City)
Next
Next
' Output:
' Canada count=2
' Contoso, Ltd Halifax
' Fabrikam, Inc. Vancouver
' United States count=1
' Margie's Travel Redmond
В этом разделе содержатся сведения о следующих областях:
Запуск примеров
Поставщики LINQ
Структура запроса LINQ
Операторы запросов LINQ в Visual Basic
Подключение к базе данных с помощью LINQ to SQL
Возможности Visual Basic, поддерживающего LINQ
Отложенное и немедленное выполнение запроса
XML в Visual Basic
Связанные ресурсы
Практические и пошаговые руководства
Запуск примеров
Для выполнения примеров во введении и в разделе "Структура" запроса LINQ, включает следующий код, который возвращает список клиентов и заказов.
' Return a list of customers.
Private Function GetCustomers() As List(Of Customer)
Return New List(Of Customer) From
{
New Customer With {.CustomerID = 1, .CompanyName = "Contoso, Ltd", .City = "Halifax", .Country = "Canada"},
New Customer With {.CustomerID = 2, .CompanyName = "Margie's Travel", .City = "Redmond", .Country = "United States"},
New Customer With {.CustomerID = 3, .CompanyName = "Fabrikam, Inc.", .City = "Vancouver", .Country = "Canada"}
}
End Function
' Return a list of orders.
Private Function GetOrders() As List(Of Order)
Return New List(Of Order) From
{
New Order With {.CustomerID = 1, .Amount = "200.00"},
New Order With {.CustomerID = 3, .Amount = "600.00"},
New Order With {.CustomerID = 1, .Amount = "300.00"},
New Order With {.CustomerID = 2, .Amount = "100.00"},
New Order With {.CustomerID = 3, .Amount = "800.00"}
}
End Function
' Customer Class.
Private Class Customer
Public Property CustomerID As Integer
Public Property CompanyName As String
Public Property City As String
Public Property Country As String
End Class
' Order Class.
Private Class Order
Public Property CustomerID As Integer
Public Property Amount As Decimal
End Class
Поставщики LINQ
Поставщик LINQ сопоставляет запросы LINQ Visual Basic с запрашиваемым источником данных. При написании запроса LINQ поставщик принимает запрос и переводит его в команды, которые источник данных будет способен выполнить. Поставщик также преобразует данные из источника в объекты, составляющие результат запроса. Наконец, он преобразует объекты в данные при отправке обновлений на источник данных.
Visual Basic содержит следующие поставщики LINQ.
Поставщик |
Описание |
LINQ to Objects |
Поставщик LINQ to Objects позволяет делать запросы к коллекциям и массивам, находящимся в памяти. Если объект поддерживает интерфейс IEnumerable или IEnumerable, поставщик 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 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 customers = GetCustomers()
Dim queryResults = From cust In customers
For Each result In queryResults
Debug.WriteLine(result.CompanyName & " " & result.Country)
Next
' Output:
' Contoso, Ltd Canada
' Margie's Travel United States
' Fabrikam, Inc. Canada
Данный пример сам по себе является допустимым запросом; однако запрос становится гораздо более мощным при добавлении нескольких предложений для уточнения результата. Например, можно добавить предложение Where для фильтрации результата по одному или нескольким значениям. Выражения запроса — это одна строка кода; можно просто добавлять дополнительные предложения в конец запроса. Можно разбить запрос на несколько строк текста для улучшения читаемости с помощью знака продолжения строки (_). В следующем примере кода показан пример запроса с предложением Where.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Другое мощное предложение запроса — предложение Select. Оно позволяет возвращать только выбранные поля из источника данных. Запросы LINQ возвращают перечислимые коллекции строго типизированных объектов. Запрос может вернуть коллекцию как анонимных, так и именованных типов. Можно использовать предложение Select для получения только одного поля из источника данных. При этом тип возвращаемой коллекции — это тип этого поля. Можно также использовать предложение Select для получения нескольких полей из источника данных. При этом тип возвращаемой коллекции — это новый анонимный тип. Можно также сопоставить возвращенные запросом поля с полями указанного именованного типа. В следующем примере кода показано выражение запроса, возвращающее коллекцию анонимных типов, члены которых заполняются данными из выбранных полей источника данных.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName, cust.Country
Запросы LINQ могут также использоваться для объединения нескольких источников данных и получения единого результата. Это можно сделать с помощью одного или нескольких предложений From или с помощью предложений Join или Group Join. В следующем примере кода показано выражение запроса, объединяющее данные клиентов и заказов и возвращающее коллекцию анонимных типов, содержащих их данные.
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers, ord In orders
Where cust.CustomerID = ord.CustomerID
Select cust, ord
For Each result In queryResults
Debug.WriteLine(result.ord.Amount & " " & result.ord.CustomerID & " " & result.cust.CompanyName)
Next
' Output:
' 200.00 1 Contoso, Ltd
' 300.00 1 Contoso, Ltd
' 100.00 2 Margie's Travel
' 600.00 3 Fabrikam, Inc.
' 800.00 3 Fabrikam, Inc.
Можно использовать предложение Group Join для получения иерархического результата запроса, содержащего коллекцию объектов клиента. Каждый объект клиента имеет свойство, содержащее коллекцию всех заказов этого клиента. В следующем примере показано выражение запроса, объединяющее данные клиентов и заказов как иерархический результат и возвращающее коллекцию анонимных типов. Запрос возвращает тип, у которого есть свойство CustomerOrders, содержащее коллекцию данных заказов клиента. У него также есть свойство OrderTotal, которое содержит общую сумму всех заказов этого клиента. (Этот запрос эквивалентен LEFT OUTER JOIN.)
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
OrderTotal = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, OrderTotal
For Each result In queryResults
Debug.WriteLine(result.OrderTotal & " " & result.CustomerID & " " & result.CompanyName)
For Each ordResult In result.CustomerOrders
Debug.WriteLine(" " & ordResult.Amount)
Next
Next
' Output:
' 500.00 1 Contoso, Ltd
' 200.00
' 300.00
' 100.00 2 Margie's Travel
' 100.00
' 1400.00 3 Fabrikam, Inc.
' 600.00
' 800.00
Имеется несколько дополнительных операторов запросов LINQ, которые можно использовать для создания мощных выражений запросов. В следующей теме этого раздела описываются различные предложения запросов, которые можно использовать в выражениях запросов. Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).
Операторы запросов LINQ в Visual Basic
Классы в поддерживающих запросы LINQ пространствах имен (в частности, System.Linq) содержат методы создания и уточнения запросов. Их можно использовать исходя из нужд приложения. Visual Basic содержит ключевые слова для наиболее общих предложений запросов, как описано в следующей таблице.
Термин |
Определение |
Предложение From или Aggregate требуется для начала запроса. Предложение From определяет коллекцию источника и переменную итерации для запроса. Например: |
|
Необязательный параметр. Объявляет набор переменных итераций для запроса. Например:
Если не указано предложение Select, то переменные итераций для запроса — это переменные итераций, указанные в предложении From или Aggregate. |
|
Необязательный параметр. Устанавливает условия фильтрации для запроса. Например: |
|
Необязательный параметр. Задает порядок сортировки столбцов в запросе. Например: |
|
Необязательный параметр. Объединяет две коллекции в одну. Например:
|
|
Необязательный параметр. Группирует элементы результата запроса. Может использоваться для применения агрегатных функций к каждой группе. Например: |
|
Необязательный параметр. Объединяет две коллекции в одну иерархическую. Например:
|
|
Предложение From или Aggregate требуется для начала запроса. Предложение Aggregate применяет одну или несколько агрегатных функций к коллекции. Например, можно использовать предложение Aggregate для вычисления суммы всех возвращенных запросом элементов.
Предложение Aggregate можно также использовать для изменения запроса. Например, можно использовать предложение Aggregate для выполнения вычислений с результатом связанного запроса. |
|
Необязательный параметр. Вычисляет значение и присваивает его новой переменной в запросе. Например: |
|
Необязательный параметр. Ограничивает значения текущей переменной итерации, чтобы исключить повторяющиеся значения в результатах запроса. Например: |
|
Необязательный параметр. Пропускает заданное число элементов в коллекции и возвращает остальные элементы. Например: |
|
Необязательный параметр. Пропускает элементы в коллекции, пока заданное условие является true и затем возвращает оставшиеся элементы. Например: |
|
Необязательный параметр. Возвращает указанное число последовательных элементов от начала коллекции. Например: |
|
Необязательный параметр. Включает элементы в коллекцию, пока заданное условие является true, и затем пропускает оставшиеся элементы. Например: |
Дополнительные сведения о предложениях запросов в Visual Basic см. в Запросы (Visual Basic).
Можно использовать дополнительные возможности запросов LINQ путем обращения к членам перечислимых и доступных для запроса типов, предоставляемых LINQ. Можно использовать эти дополнительные возможности, вызвав конкретный оператор запроса на результате выражения запроса. Например, код следующего примера использует метод Union``1 для объединения результатов двух запросов в один. Он использует метод ToList``1 для возвращения результата запроса в виде универсального списка.
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. |
|
Содержит справочные сведения о предложениях запросов, которые доступны в Visual Basic. |
|
Содержит общие сведения, рекомендации по программированию и примеры для LINQ. |
|
Содержит общие сведения, рекомендации по программированию и примеры для LINQ to SQL. |
|
Содержит общие сведения, рекомендации по программированию и примеры для LINQ to Objects. |
|
Содержит ссылки на общие сведения, рекомендации по программированию и примеры для LINQ ADO.NET. |
|
Содержит общие сведения, рекомендации по программированию и примеры для LINQ to XML. |
Практические и пошаговые руководства
Практическое руководство. Выполнение запросов к базе данных с помощью LINQ (Visual Basic)
Практическое руководство. Вызов хранимой процедуры с помощью LINQ (Visual Basic)
Практическое руководство. Изменение данных в базе данных с помощью LINQ (Visual Basic)
Практическое руководство. Сортировка результатов запроса с помощью LINQ (Visual Basic)
Практическое руководство. Фильтрование результатов запроса с помощью LINQ (Visual Basic)
Пошаговое руководство. Создание классов LINQ to SQL (реляционный конструктор объектов)
Главы в популярных книгах
Chapter 17: LINQ в Programming Visual Basic 2008
См. также
Задачи
Основные понятия
Общие сведения о LINQ to XML в Visual Basic
Общие сведения о LINQ to DataSet
Методы DataContext (реляционный конструктор объектов)