Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Language-Integrated Запрос (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 ", добавьте следующий код, который возвращает списки клиентов и заказов.
' 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 для объектов | Поставщик объектов LINQ to Objects позволяет запрашивать коллекции и массивы в памяти. Если объект поддерживает либо интерфейс IEnumerable, либо интерфейс IEnumerable<T>, поставщик LINQ to Objects позволяет выполнять запросы к нему. Вы можете включить функциональность LINQ to Objects, импортируя пространство имен System.Linq, которое импортируется по умолчанию для всех проектов на Visual Basic. Дополнительные сведения о поставщике объектов LINQ to Objects см. в разделе LINQ to Objects. |
LINQ to SQL | Поставщик LINQ to SQL позволяет запрашивать и изменять данные в базе данных SQL Server. Это упрощает сопоставление объектной модели для приложения с таблицами и объектами в базе данных. Visual Basic упрощает работу с LINQ to SQL, включая реляционный конструктор объектов (конструктор O/R). Этот конструктор используется для создания объектной модели в приложении, которое сопоставляется с объектами в базе данных. Конструктор O/R также предоставляет функции для сопоставления хранимых процедур и функций с DataContext объектом, который управляет взаимодействием с базой данных и сохраняет состояние для оптимистических проверок параллелизма. Дополнительные сведения о поставщике LINQ to SQL см. в разделе LINQ to SQL. Дополнительные сведения об реляционном конструкторе объектов см. в статье LINQ to SQL Tools в Visual Studio. |
LINQ to XML | Поставщик LINQ to XML позволяет запрашивать и изменять XML. Можно изменять XML в памяти или загружать и сохранять XML в файле. Кроме того, поставщик LINQ to XML позволяет использовать XML-литералы и свойства XML-оси, позволяющие записывать XML непосредственно в вашем коде Visual Basic. Дополнительные сведения см. в разделе XML. |
LINQ to DataSet | Поставщик LINQ to DataSet позволяет запрашивать и обновлять данные в наборе данных ADO.NET. Вы можете добавить возможности LINQ в приложения, использующие наборы данных, чтобы упростить и расширить возможности для запроса, агрегирования и обновления данных в наборе данных. Дополнительные сведения см. в разделе LINQ to DataSet. |
Структура запроса LINQ
Запрос LINQ, часто называемый выражением запроса, состоит из сочетания предложений запросов, определяющих источники данных и переменные итерации для запроса. Выражение запроса также может содержать инструкции по сортировке, фильтрации, группировке и присоединению или вычислениям для применения к исходным данным. Синтаксис выражения запроса напоминает синтаксис SQL; таким образом, вы можете найти большую часть синтаксиса знакомую.
Выражение запроса начинается с From
предложения. Это предложение определяет исходные данные для запроса и переменные, используемые для ссылки на каждый элемент исходных данных по отдельности. Эти переменные называются переменными диапазона или переменными итерации. Предложение From
обязательно для запроса, за исключением запросов Aggregate
, где предложение From
является необязательным. После определения области и источника запроса в клаузах From
или Aggregate
можно включить любое сочетание клауз запроса для уточнения запроса. Дополнительные сведения о предложениях запросов см. в разделе Visual Basic LINQ Query Operators в этом разделе ниже. Например, следующий запрос определяет исходную коллекцию данных о клиентах как переменную 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
свойство, которое включает общую сумму всех заказов этого клиента. (Этот запрос эквивалентен левому внешнему соединению.)
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
Классы в System.Linq пространстве имен и других пространствах имен, поддерживающих запросы LINQ, включают методы, которые можно вызывать для создания и уточнения запросов в зависимости от потребностей приложения. Visual Basic содержит ключевые слова для следующих распространенных предложений запросов. Дополнительные сведения о предложениях запросов Visual Basic см. в разделе "Запросы".
Предложение From
Для начала запроса требуется либо From
предложение, либо Aggregate
предложение. Предложение From
указывает исходную коллекцию и переменную итерации для запроса. Рассмотрим пример.
' Returns the company name for all customers for which
' the Country is equal to "Canada".
Dim names = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName
Предложение Select
Необязательно.
УсловиеSelect
объявляет набор переменных итерации для выполнения запроса. Рассмотрим пример.
' Returns the company name and ID value for each
' customer as a collection of a new anonymous type.
Dim customerList = From cust In customers
Select cust.CompanyName, cust.CustomerID
Select
Если предложение не указано, переменные итерации для запроса состоят из переменных итерации, указанных в From
или Aggregate
предложении.
Предложение Where
Необязательно. Предложение Where
указывает условие фильтрации для запроса. Рассмотрим пример.
' Returns all product names for which the Category of
' the product is "Beverages".
Dim names = From product In products
Where product.Category = "Beverages"
Select product.Name
Оператор "Order By"
Необязательно. Предложение Order By
указывает порядок сортировки столбцов в запросе. Рассмотрим пример.
' Returns a list of books sorted by price in
' ascending order.
Dim titlesAscendingPrice = From b In books
Order By b.price
Предложение Join
Необязательно.
Join
Выражение объединяет две коллекции в одну коллекцию. Рассмотрим пример.
' Returns a combined collection of all of the
' processes currently running and a descriptive
' name for the process taken from a list of
' descriptive names.
Dim processes = From proc In Process.GetProcesses
Join desc In processDescriptions
On proc.ProcessName Equals desc.ProcessName
Select proc.ProcessName, proc.Id, desc.Description
Группировка данных с использованием Group By
Необязательно. Предложение Group By
группит элементы результата запроса. Его можно использовать для применения агрегатных функций к каждой группе. Рассмотрим пример.
' Returns a list of orders grouped by the order date
' and sorted in ascending order by the order date.
Dim orderList = From order In orders
Order By order.OrderDate
Group By OrderDate = order.OrderDate
Into OrdersByDate = Group
Предложение "Присоединение к группе"
Необязательно.
КлаузаGroup Join
объединяет две коллекции в одну иерархическую коллекцию. Рассмотрим пример.
' Returns a combined collection of customers and
' customer orders.
Dim customerList = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
TotalOfOrders = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, TotalOfOrders
клаузула агрегации
Либо Aggregate
условие, либо From
условие требуется для начала запроса. Предложение Aggregate
применяет к коллекции одну или несколько агрегатных функций. Например, можно использовать Aggregate
предложение для вычисления суммы для всех элементов, возвращаемых запросом, как показано в следующем примере.
' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
Into Sum(order.Amount)
Можно также использовать Aggregate
предложение для изменения запроса. Например, можно использовать Aggregate
предложение для вычисления связанной коллекции запросов. Рассмотрим пример.
' Returns the customer company name and largest
' order amount for each customer.
Dim customerMax = From cust In customers
Aggregate order In cust.Orders
Into MaxOrder = Max(order.Amount)
Select cust.CompanyName, MaxOrder
Конструкция Let
Необязательно.
ПредложениеLet
вычисляет значение и назначает его новой переменной в запросе. Рассмотрим пример.
' Returns a list of products with a calculation of
' a ten percent discount.
Dim discountedProducts = From prod In products
Let Discount = prod.UnitPrice * 0.1
Where Discount >= 50
Select prod.Name, prod.UnitPrice, Discount
Отдельный пункт
Необязательно. Предложение Distinct
ограничивает значения текущей переменной итерации, чтобы исключить повторяющиеся значения в результатах запроса. Рассмотрим пример.
' Returns a list of cities with no duplicate entries.
Dim cities = From item In customers
Select item.City
Distinct
Пропустить пункт
Необязательно.
ПредложениеSkip
проходит указанное число элементов в коллекции, а затем возвращает оставшиеся элементы. Рассмотрим пример.
' Returns a list of customers. The first 10 customers
' are ignored and the remaining customers are
' returned.
Dim customerList = From cust In customers
Skip 10
Пропустить предложение "Пока"
Необязательно. Условие Skip While
обходит элементы коллекции до тех пор, пока выполняется указанное условие true
, а затем возвращает остальные элементы. Рассмотрим пример.
' Returns a list of customers. The query ignores all
' customers until the first customer for whom
' IsSubscriber returns false. That customer and all
' remaining customers are returned.
Dim customerList = From cust In customers
Skip While IsSubscriber(cust)
Статья Take
Необязательно.
ПредложениеTake
возвращает указанное число смежных элементов из начала коллекции. Рассмотрим пример.
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Предложение Take While
Необязательно. Предложение Take While
включает элементы в коллекцию до тех пор, пока указано условие true
, после чего оставшиеся элементы игнорируются. Рассмотрим пример.
' Returns a list of customers. The query returns
' customers until the first customer for whom
' HasOrders returns false. That customer and all
' remaining customers are ignored.
Dim customersWithOrders = From cust In customers
Order By cust.Orders.Count Descending
Take While HasOrders(cust)
Использование дополнительных функций запроса LINQ
Дополнительные функции запроса LINQ можно использовать, вызывая элементы перечисленных и запрашиваемых типов, предоставляемых LINQ. Эти дополнительные возможности можно использовать, вызвав конкретный оператор запроса для результата выражения запроса. Например, в следующем примере метод используется Enumerable.Union для объединения результатов двух запросов в один результат запроса. Он использует Enumerable.ToList метод для возврата результата запроса в виде универсального списка.
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 Classes . Откроется конструктор реляционных объектов (конструктор операций ввода-вывода). Конструктор операций ввода-вывода позволяет перетащить элементы, к которым вы хотите получить доступ в коде, изобозревателя баз данных/ в область конструктора. Файл LINQ to SQL добавляет DataContext объект в проект. Этот объект включает свойства и коллекции для таблиц и представлений, к которым требуется доступ, а также методы для вызова хранимых процедур. После сохранения изменений в файле LINQ to SQL (DBML) вы можете получить доступ к этим объектам в коде, ссылаясь DataContext на объект, определенный конструктором O/R. Объект DataContext вашего проекта получает имя на основе названия файла LINQ to SQL. Например, файл LINQ to SQL с именем Northwind.dbml создаст DataContext объект с именем NorthwindDataContext
.
Примеры с пошаговыми инструкциями см. в статье "Практическое руководство. Запрос базы данных и практическое руководство. Вызов хранимой процедуры".
Функции Visual Basic, поддерживающие LINQ
Visual Basic включает другие важные функции, которые упрощают использование LINQ и сокращают объем кода, который необходимо записать для выполнения запросов LINQ. К ним относятся следующие:
Анонимные типы, позволяющие создать новый тип на основе результата запроса.
Неявно типизированные переменные, позволяющие отложить указание типа и разрешить компилятору определить тип на основе результата запроса.
Методы расширения, позволяющие расширить существующий тип с собственными методами без изменения самого типа.
Дополнительные сведения см. в разделе "Функции Visual Basic", поддерживающие LINQ.
Отложенное и немедленное выполнение запросов
Выполнение запроса отличается от создания запроса. После создания запроса его выполнение активируется отдельным механизмом. Запрос можно выполнить, как только он определен (немедленное выполнение), или определение может храниться, и запрос можно выполнить позже (отложенное выполнение).
По умолчанию при создании запроса сам запрос не выполняется немедленно. Вместо этого определение запроса хранится в переменной, которая используется для ссылки на результат запроса. При доступе к переменной результата запроса позже в коде, например в For…Next
цикле, выполняется запрос. Этот процесс называется отложенным выполнением.
Запросы могут выполняться сразу после их определения, что называется немедленным выполнением. Немедленное выполнение можно активировать, применяя метод, требующий доступа к отдельным элементам результата запроса. Это может быть результатом включения агрегатной функции, например Count
, Sum
, , Average
Min
или Max
. Дополнительные сведения об агрегатных функциях см. в разделе Aggregate Clause.
Использование методов ToList
или ToArray
также приведет к их немедленному выполнению. Это может быть полезно, если вы хотите немедленно выполнить запрос и кэшировать результаты. Дополнительные сведения об этих методах см. в разделе "Преобразование типов данных".
Дополнительные сведения о выполнении запросов см. в статье "Написание первого запроса LINQ".
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.
Связанные ресурсы
Тема | Описание |
---|---|
XML | Описывает функции XML в Visual Basic, которые можно запрашивать и которые позволяют включать XML в качестве объектов данных первого класса в код Visual Basic. |
Запросы | Предоставляет справочные сведения о конструкции запросов, имеющихся в Visual Basic. |
LINQ (запросLanguage-Integrated) | Содержит общие сведения, рекомендации по программированию и примеры для LINQ. |
LINQ to SQL | Содержит общие сведения, рекомендации по программированию и примеры для LINQ to SQL. |
LINQ к объектам | Содержит общую информацию, рекомендации по программированию и примеры для LINQ to Objects. |
LINQ to ADO.NET (страница портала) | Содержит ссылки на общие сведения, рекомендации по программированию и примеры для LINQ to ADO.NET. |
LINQ to XML | Содержит общие сведения, рекомендации по программированию и примеры для LINQ to XML. |
Инструкции и пошаговое руководство
Практическое руководство. Запрос базы данных
Практическое руководство. Вызов хранимой процедуры
Практическое руководство. Изменение данных в базе данных
Как объединить данные с помощью соединений
Практическое руководство. Сортировка результатов запроса
Практическое руководство. Фильтрация результатов запроса
Как: подсчитывать, суммировать или вычислять среднее значение данных
Практическое руководство. Поиск минимального или максимального значения в результатах запроса
Избранные главы книги
Глава 17. LINQ в программировании Visual Basic 2008