Introdução ao LINQ no Visual Basic
O LINQ (Language-Integrated Query) adiciona recursos de consulta ao Visual Basic e fornece recursos simples e poderosos quando você trabalha com todos os tipos de dados. Em vez de enviar uma consulta para um banco de dados a ser processado ou trabalhar com sintaxe de consulta diferente para cada tipo de dados que você está pesquisando, o LINQ introduz consultas como parte da linguagem Visual Basic. Ele usa uma sintaxe unificada, independentemente do tipo de dados.
O LINQ permite consultar dados de um banco de dados SQL Server, XML, matrizes e coleções na memória, conjuntos de dados ADO.NET ou qualquer outra fonte de dados remota ou local que ofereça suporte ao LINQ. Você pode fazer tudo isso com elementos comuns da linguagem Visual Basic. Como suas consultas são escritas na linguagem Visual Basic, os resultados da consulta são retornados como objetos fortemente tipados. Esses objetos suportam o IntelliSense, que permite que você escreva código mais rapidamente e detete erros em suas consultas em tempo de compilação em vez de em tempo de execução. As consultas LINQ podem ser usadas como fonte de consultas adicionais para refinar os resultados. Eles também podem ser vinculados a controles para que os usuários possam visualizar e modificar facilmente os resultados da consulta.
Por exemplo, o exemplo de código a seguir mostra uma consulta LINQ que retorna uma lista de clientes de uma coleção e os agrupa com base em sua localização.
' 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
Executando os exemplos
Para executar os exemplos na introdução e na seção Estrutura de uma consulta LINQ, inclua o código a seguir, que retorna listas de clientes e pedidos.
' 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
Fornecedores LINQ
Um provedor LINQ mapeia suas consultas LINQ do Visual Basic para a fonte de dados que está sendo consultada. Quando você escreve uma consulta LINQ, o provedor pega essa consulta e a traduz em comandos que a fonte de dados poderá executar. O provedor também converte dados da origem para os objetos que compõem o resultado da consulta. Finalmente, ele converte objetos em dados quando você envia atualizações para a fonte de dados.
Visual Basic inclui os seguintes provedores LINQ.
Provider | Description |
---|---|
LINQ para objetos | O provedor LINQ to Objects permite que você consulte coleções e matrizes na memória. Se um objeto suportar a IEnumerable interface ou IEnumerable<T> , o provedor LINQ to Objects permitirá que você o consulte. Você pode habilitar o provedor LINQ to Objects importando o namespace, que é importado System.Linq por padrão para todos os projetos do Visual Basic. Para obter mais informações sobre o provedor LINQ to Objects, consulte LINQ to Objects. |
LINQ para SQL | O provedor LINQ to SQL permite consultar e modificar dados em um banco de dados do SQL Server. Isso facilita o mapeamento do modelo de objeto de um aplicativo para as tabelas e objetos em um banco de dados. O Visual Basic facilita o trabalho com LINQ to SQL incluindo o Object Relational Designer (O/R Designer). Esse designer é usado para criar um modelo de objeto em um aplicativo que mapeia para objetos em um banco de dados. O O/R Designer também fornece funcionalidade para mapear procedimentos armazenados e funções para o DataContext objeto, que gerencia a comunicação com o banco de dados e armazena o estado para verificações de simultaneidade otimistas. Para obter mais informações sobre o provedor LINQ to SQL, consulte LINQ to SQL. Para obter mais informações sobre o Object Relational Designer, consulte LINQ to SQL Tools in Visual Studio. |
LINQ para XML | O provedor LINQ to XML permite consultar e modificar XML. Você pode modificar XML na memória ou pode carregar XML e salvar XML em um arquivo. Além disso, o provedor LINQ to XML habilita literais XML e propriedades de eixo XML que permitem que você escreva XML diretamente em seu código do Visual Basic. Para obter mais informações, consulte XML. |
LINQ para DataSet | O provedor LINQ to DataSet permite consultar e atualizar dados em um conjunto de dados ADO.NET. Você pode adicionar o poder do LINQ a aplicativos que usam conjuntos de dados para simplificar e estender seus recursos de consulta, agregação e atualização dos dados em seu conjunto de dados. Para obter mais informações, consulte LINQ to DataSet. |
Estrutura de uma consulta LINQ
Uma consulta LINQ, geralmente referida como uma expressão de consulta, consiste em uma combinação de cláusulas de consulta que identificam as fontes de dados e as variáveis de iteração para a consulta. Uma expressão de consulta também pode incluir instruções para classificar, filtrar, agrupar e juntar, ou cálculos para aplicar aos dados de origem. A sintaxe da expressão de consulta é semelhante à sintaxe do SQL; portanto, você pode achar muito da sintaxe familiar.
Uma expressão de consulta começa com uma From
cláusula. Esta cláusula identifica os dados de origem para uma consulta e as variáveis que são usadas para se referir a cada elemento dos dados de origem individualmente. Essas variáveis são denominadas variáveis de intervalo ou variáveis de iteração. A From
cláusula é necessária para uma consulta, exceto para Aggregate
consultas, onde a From
cláusula é opcional. Depois que o escopo e a origem da consulta forem identificados nas From
cláusulas or Aggregate
, você poderá incluir qualquer combinação de cláusulas de consulta para refinar a consulta. Para obter detalhes sobre cláusulas de consulta, consulte Operadores de consulta LINQ do Visual Basic mais adiante neste tópico. Por exemplo, a consulta a seguir identifica uma coleção de origem de dados do cliente como a customers
variável e uma variável de iteração chamada 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
Este exemplo é uma consulta válida por si só; No entanto, a consulta se torna muito mais poderosa quando você adiciona mais cláusulas de consulta para refinar o resultado. Por exemplo, você pode adicionar uma Where
cláusula para filtrar o resultado por um ou mais valores. As expressões de consulta são uma única linha de código; Você pode apenas acrescentar cláusulas de consulta adicionais ao final da consulta. Você pode dividir uma consulta em várias linhas de texto para melhorar a legibilidade usando o caractere de continuação de linha sublinhado (_). O exemplo de código a seguir mostra um exemplo de uma consulta que inclui uma Where
cláusula.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Outra cláusula de consulta poderosa é a Select
cláusula, que permite retornar apenas campos selecionados da fonte de dados. As consultas LINQ retornam coleções enumeráveis de objetos fortemente tipados. Uma consulta pode retornar uma coleção de tipos anônimos ou tipos nomeados. Você pode usar a Select
cláusula para retornar apenas um único campo da fonte de dados. Quando você faz isso, o tipo da coleção retornada é o tipo desse único campo. Você também pode usar a Select
cláusula para retornar vários campos da fonte de dados. Quando você faz isso, o tipo da coleção retornada é um novo tipo anônimo. Você também pode fazer a correspondência entre os campos retornados pela consulta e os campos de um tipo nomeado especificado. O exemplo de código a seguir mostra uma expressão de consulta que retorna uma coleção de tipos anônimos que têm membros preenchidos com dados dos campos selecionados da fonte de dados.
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName, cust.Country
As consultas LINQ também podem ser usadas para combinar várias fontes de dados e retornar um único resultado. Isso pode ser feito com uma ou mais From
cláusulas, ou usando as Join
cláusulas ou Group Join
consulta. O exemplo de código a seguir mostra uma expressão de consulta que combina dados de cliente e pedido e retorna uma coleção de tipos anônimos contendo dados de cliente e pedido.
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.
Você pode usar a Group Join
cláusula para criar um resultado de consulta hierárquica que contenha uma coleção de objetos do cliente. Cada objeto de cliente tem uma propriedade que contém uma coleção de todos os pedidos para esse cliente. O exemplo de código a seguir mostra uma expressão de consulta que combina dados de cliente e ordem como um resultado hierárquico e retorna uma coleção de tipos anônimos. A consulta retorna um tipo que inclui uma CustomerOrders
propriedade que contém uma coleção de dados de ordem para o cliente. Ele também inclui uma OrderTotal
propriedade que contém a soma dos totais de todos os pedidos para esse cliente. (Esta consulta é equivalente a uma JUNÇÃO EXTERNA ESQUERDA.)
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
Há vários operadores de consulta LINQ adicionais que você pode usar para criar expressões de consulta poderosas. A próxima seção deste tópico discute as várias cláusulas de consulta que você pode incluir em uma expressão de consulta. Para obter detalhes sobre cláusulas de consulta do Visual Basic, consulte Consultas.
Operadores de consulta LINQ do Visual Basic
As classes no System.Linq namespace e os outros namespaces que suportam consultas LINQ incluem métodos que você pode chamar para criar e refinar consultas com base nas necessidades do seu aplicativo. Visual Basic inclui palavras-chave para as seguintes cláusulas de consulta comuns. Para obter detalhes sobre cláusulas de consulta do Visual Basic, consulte Consultas.
Da cláusula
Uma From
cláusula ou uma Aggregate
cláusula é necessária para iniciar uma consulta. Uma From
cláusula especifica uma coleção de origem e uma variável de iteração para uma consulta. Por exemplo:
' 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
Cláusula de seleção
Opcional. Uma Select
cláusula declara um conjunto de variáveis de iteração para uma consulta. Por exemplo:
' 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
Se uma Select
cláusula não for especificada, as variáveis de iteração para a consulta consistirão nas variáveis de iteração especificadas pela From
cláusula ou Aggregate
.
Cláusula de onde
Opcional. Uma Where
cláusula especifica uma condição de filtragem para uma consulta. Por exemplo:
' 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
Encomendar por cláusula
Opcional. Uma Order By
cláusula especifica a ordem de classificação das colunas em uma consulta. Por exemplo:
' Returns a list of books sorted by price in
' ascending order.
Dim titlesAscendingPrice = From b In books
Order By b.price
Cláusula de adesão
Opcional. Uma Join
cláusula combina duas coleções em uma única coleção. Por exemplo:
' 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
Cláusula Group By
Opcional. Uma Group By
cláusula agrupa os elementos de um resultado de consulta. Ele pode ser usado para aplicar funções agregadas a cada grupo. Por exemplo:
' 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
Cláusula de adesão ao grupo
Opcional. Uma Group Join
cláusula combina duas coleções em uma única coleção hierárquica. Por exemplo:
' 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
Cláusula agregada
Uma Aggregate
cláusula ou uma From
cláusula é necessária para iniciar uma consulta. Uma Aggregate
cláusula aplica uma ou mais funções agregadas a uma coleção. Por exemplo, você pode usar a Aggregate
cláusula para calcular uma soma para todos os elementos retornados por uma consulta, como faz o exemplo a seguir.
' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
Into Sum(order.Amount)
Você também pode usar a Aggregate
cláusula para modificar uma consulta. Por exemplo, você pode usar a Aggregate
cláusula para executar um cálculo em uma coleção de consultas relacionada. Por exemplo:
' 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
Cláusula de arrendamento
Opcional. Uma Let
cláusula calcula um valor e o atribui a uma nova variável na consulta. Por exemplo:
' 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
Cláusula distinta
Opcional. Uma Distinct
cláusula restringe os valores da variável de iteração atual para eliminar valores duplicados nos resultados da consulta. Por exemplo:
' Returns a list of cities with no duplicate entries.
Dim cities = From item In customers
Select item.City
Distinct
Cláusula de pulo
Opcional. Uma Skip
cláusula ignora um número especificado de elementos em uma coleção e, em seguida, retorna os elementos restantes. Por exemplo:
' 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
Cláusula Skip While
Opcional. Uma Skip While
cláusula ignora elementos em uma coleção, desde que uma condição especificada seja true
e, em seguida, retorna os elementos restantes. Por exemplo:
' 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)
Cláusula Take
Opcional. Uma Take
cláusula retorna um número especificado de elementos contíguos desde o início de uma coleção. Por exemplo:
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Cláusula Take While
Opcional. Uma Take While
cláusula inclui elementos em uma coleção, desde que uma condição especificada seja true
e ignore os elementos restantes. Por exemplo:
' 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)
Usar recursos de consulta LINQ adicionais
Você pode usar recursos de consulta LINQ adicionais chamando membros dos tipos enumeráveis e consultáveis fornecidos pelo LINQ. Você pode usar esses recursos adicionais chamando um operador de consulta específico no resultado de uma expressão de consulta. Por exemplo, o exemplo a seguir usa o Enumerable.Union método para combinar os resultados de duas consultas em um resultado de consulta. Ele usa o Enumerable.ToList método para retornar o resultado da consulta como uma lista genérica.
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
Para obter detalhes sobre recursos adicionais do LINQ, consulte Visão geral dos operadores de consulta padrão.
Conectar-se a um banco de dados usando LINQ to SQL
No Visual Basic, você identifica os objetos de banco de dados do SQL Server, como tabelas, exibições e procedimentos armazenados, que deseja acessar usando um arquivo LINQ to SQL. Um arquivo LINQ to SQL tem uma extensão .dbml.
Quando você tiver uma conexão válida com um banco de dados do SQL Server, poderá adicionar um modelo de item LINQ to SQL Classes ao seu projeto. Isso exibirá o Object Relational Designer (designer O/R). O O/R Designer permite que você arraste os itens que você deseja acessar em seu código do Gerenciador de Banco de Dados do Gerenciador de Servidores/ para a superfície do designer. O arquivo LINQ to SQL adiciona um DataContext objeto ao seu projeto. Este objeto inclui propriedades e coleções para as tabelas e exibições que você deseja acessar e métodos para os procedimentos armazenados que você deseja chamar. Depois de salvar as alterações no arquivo LINQ to SQL (.dbml), você pode acessar esses objetos em seu código fazendo referência ao DataContext objeto definido pelo O/R Designer. O DataContext objeto para seu projeto é nomeado com base no nome do seu arquivo LINQ to SQL. Por exemplo, um arquivo LINQ to SQL chamado Northwind.dbml criará um DataContext objeto chamado NorthwindDataContext
.
Para obter exemplos com instruções passo a passo, consulte Como consultar um banco de dados e Como chamar um procedimento armazenado.
Recursos do Visual Basic que suportam LINQ
Visual Basic inclui outros recursos notáveis que tornam o uso do LINQ simples e reduzem a quantidade de código que você deve escrever para executar consultas LINQ. Estes incluem:
Tipos anônimos, que permitem criar um novo tipo com base em um resultado de consulta.
Variáveis digitadas implicitamente, que permitem adiar a especificação de um tipo e permitir que o compilador infera o tipo com base no resultado da consulta.
Métodos de extensão, que permitem estender um tipo existente com seus próprios métodos sem modificar o próprio tipo.
Para obter detalhes, consulte Recursos do Visual Basic que suportam LINQ.
Execução de consulta adiada e imediata
A execução da consulta é separada da criação de uma consulta. Depois que uma consulta é criada, sua execução é acionada por um mecanismo separado. Uma consulta pode ser executada assim que é definida (execução imediata), ou a definição pode ser armazenada e a consulta pode ser executada posteriormente (execução diferida).
Por padrão, quando você cria uma consulta, a consulta em si não é executada imediatamente. Em vez disso, a definição de consulta é armazenada na variável usada para fazer referência ao resultado da consulta. Quando a variável de resultado da consulta é acessada posteriormente no código, como em um For…Next
loop, a consulta é executada. Este processo é conhecido como execução diferida.
As consultas também podem ser executadas quando são definidas, o que é referido como execução imediata. Você pode acionar a execução imediata aplicando um método que requer acesso a elementos individuais do resultado da consulta. Isso pode ser o resultado da inclusão de uma função agregada, como Count
, Sum
, Average
, Min
, ou Max
. Para obter mais informações sobre funções agregadas, consulte Cláusula agregada.
O uso dos métodos ou ToArray
também forçará a ToList
execução imediata. Isso pode ser útil quando você deseja executar a consulta imediatamente e armazenar os resultados em cache. Para obter mais informações sobre esses métodos, consulte Convertendo tipos de dados.
Para obter mais informações sobre a execução de consultas, consulte Escrevendo sua primeira consulta LINQ.
XML em Visual Basic
Os recursos XML no Visual Basic incluem literais XML e propriedades de eixo XML, que permitem que você facilmente criar, acessar, consultar e modificar XML em seu código. Os literais XML permitem que você escreva XML diretamente em seu código. O compilador do Visual Basic trata o XML como um objeto de dados de primeira classe.
O exemplo de código a seguir mostra como criar um elemento XML, acessar seus subelementos e atributos e consultar o conteúdo do elemento usando 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
Para obter mais informações, consulte XML.
Recursos relacionados
Tópico | Description |
---|---|
XML | Descreve os recursos XML no Visual Basic que podem ser consultados e que permitem que você inclua XML como objetos de dados de primeira classe em seu código do Visual Basic. |
Consultas | Fornece informações de referência sobre as cláusulas de consulta que estão disponíveis no Visual Basic. |
LINQ (Consulta Integrada à Linguagem) | Inclui informações gerais, orientação de programação e exemplos para LINQ. |
LINQ para SQL | Inclui informações gerais, orientação de programação e exemplos para LINQ to SQL. |
LINQ para objetos | Inclui informações gerais, orientação de programação e exemplos para LINQ to Objects. |
LINQ to ADO.NET (Página do Portal) | Inclui links para informações gerais, orientações de programação e exemplos para o LINQ to ADO.NET. |
LINQ para XML | Inclui informações gerais, orientação de programação e exemplos para LINQ to XML. |
Como fazer e tópicos passo a passo
Como: Consultar um banco de dados
Como: Chamar um procedimento armazenado
Como modificar dados em um banco de dados
Como: Combinar dados com associações
Como: Classificar resultados da consulta
Como: Filtrar resultados da consulta
Como contar, somar ou média de dados
Como: Localizar o valor mínimo ou máximo em um resultado de consulta
Capítulos de livros em destaque
Capítulo 17: LINQ na programação do Visual Basic 2008