Introdução a LINQ no Visual Basic
Language-Integrated Query (LINQ) 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 do 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 dê suporte ao LINQ. Você pode fazer tudo isso com elementos comuns da linguagem do Visual Basic. Como suas consultas são escritas na linguagem Visual Basic, os resultados da consulta são retornados como objetos fortemente tipado. Esses objetos dão suporte ao IntelliSense, o que permite escrever código mais rapidamente e detectar erros em suas consultas no tempo de compilação, em vez de em tempo de execução. As consultas LINQ podem ser usadas como a origem de consultas adicionais para refinar resultados. Eles também podem ser associados a controles para que os usuários possam exibir 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
Como executar os exemplos
Para executar os exemplos na introdução e na estrutura de uma seção de 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
Provedores 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 usa essa consulta e a converte 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. Por fim, ele converte objetos em dados quando você envia atualizações para a fonte de dados.
O Visual Basic inclui os seguintes provedores LINQ.
Provedor | Descrição |
---|---|
Objetos LINQ to | O provedor de LINQ to Objects permite consultar coleções e matrizes na memória. Se um objeto for compatível com a interface ou IEnumerable a IEnumerable<T> interface, o provedor de LINQ to Objects permitirá que você o consulte. Você pode habilitar o provedor de LINQ to Objects importando o System.Linq namespace, que é importado por padrão para todos os projetos do Visual Basic. Para obter mais informações sobre o provedor de LINQ to Objects, consulte LINQ to Objects. |
LINQ to SQL | O provedor de LINQ to SQL permite consultar e modificar dados em um banco de dados SQL Server. Isso facilita o mapeamento do modelo de objeto para 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 (Designer O/R). Este designer é usado para criar um modelo de objeto em um aplicativo que mapeia para objetos em um banco de dados. O Designer de O/R também fornece funcionalidade para mapear procedimentos armazenados e funções para o objeto, que gerencia a DataContext 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 de LINQ to SQL, consulte LINQ to SQL. Para obter mais informações sobre o Designer Relacional de Objetos, consulte Ferramentas do LINQ to SQL no Visual Studio. |
LINQ to XML | O provedor de LINQ to XML permite consultar e modificar XML. Você pode modificar o XML na memória ou carregar XML e salvar XML em um arquivo. Além disso, o provedor de LINQ to XML habilita literais XML e propriedades do eixo XML que permitem que você escreva XML diretamente no código do Visual Basic. Para obter mais informações, confira XML. |
LINQ to DataSet | O provedor de 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 para consultar, agregar e atualizar os dados em seu conjunto de dados. Para obter mais informações, consulte LINQ to DataSet. |
Estrutura de uma consulta LINQ
Uma consulta LINQ, geralmente conhecida 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 classificação, filtragem, agrupamento e junção ou cálculos a serem aplicados 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. Essa cláusula identifica os dados de origem de 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 variáveis de intervalo nomeadas ou variáveis de iteração. A From
cláusula é necessária para uma consulta, exceto para Aggregate
consultas, em que a From
cláusula é opcional. Depois que o escopo e a origem da consulta forem identificados nas cláusulas ou From
cláusulasAggregate
, 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 simplesmente acrescentar cláusulas de consulta adicionais ao final da consulta. Você pode interromper 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 que você retorne apenas campos selecionados da fonte de dados. As consultas LINQ retornam coleções enumeráveis de objetos fortemente tipado. 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 corresponder os campos retornados pela consulta aos 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 que contêm 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 contém uma coleção de objetos de 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 pedido como 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 pedido para o cliente. Ele também inclui uma OrderTotal
propriedade que contém a soma dos totais de todos os pedidos para esse cliente. (Essa consulta é equivalente a 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
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 nos outros namespaces que dão suporte a consultas LINQ incluem métodos que você pode chamar para criar e refinar consultas com base nas necessidades do aplicativo. O 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.
Cláusula From
Uma From
cláusula ou uma cláusula Aggregate
é necessária para iniciar uma consulta. Uma cláusula From
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 Select
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 consistem nas variáveis de iteração especificadas pela From
cláusula ou Aggregate
pela cláusula.
Cláusula Where
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
cláusula Order By
Opcional. Uma Order By
cláusula especifica a ordem de classificação para 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 Join
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 de agregação 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 Group Join
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 Aggregate
Uma Aggregate
cláusula ou uma cláusula From
é necessária para iniciar uma consulta. Uma Aggregate
cláusula aplica uma ou mais funções de agregação 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 o exemplo a seguir faz.
' 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 Let
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 Distinct
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 Skip
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, contanto que uma condição especificada seja true
e retorne 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 do 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 adicionais de consulta LINQ
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 a 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 SQL Server, como tabelas, exibições e procedimentos armazenados, que você deseja acessar usando um arquivo LINQ to SQL. Um arquivo LINQ to SQL tem uma extensão .dbml.
Quando você tem uma conexão válida com um banco de dados SQL Server, pode adicionar um modelo de item LINQ to SQL Classes ao seu projeto. Isso exibirá o Object Relational Designer (designer de O/R). O Designer de O/R permite arrastar os itens que você deseja acessar em seu código doGerenciador de Servidores/Gerenciador do Banco de Dados para a superfície do designer. O arquivo LINQ to SQL adiciona um DataContext objeto ao seu projeto. Esse objeto inclui propriedades e coleções para as tabelas e exibições às quais você deseja acessar e métodos para os procedimentos armazenados que você deseja chamar. Depois de salvar suas alterações no arquivo LINQ to SQL (.dbml), você poderá acessar esses objetos em seu código fazendo referência ao DataContext objeto definido pelo Designer O/R. O DataContext objeto para seu projeto é nomeado com base no nome do 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
O Visual Basic inclui outros recursos notáveis que simplificam o uso do LINQ e reduzem a quantidade de código que você deve escrever para executar consultas LINQ. Elas incluem o seguinte:
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 permitem 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 os recursos do Visual Basic que dão suporte a 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 é disparada 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 adiada).
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 referenciar o 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. Esse processo é chamado de execução adiada.
As consultas também podem ser executadas quando são definidas, o que é chamado de execução imediata. Você pode disparar 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 de agregação, comoCount
, Sum
, Average
, Min
ou Max
. Para obter mais informações sobre funções de agregação, consulte Cláusula agregada.
Usar os ToList
métodos ou ToArray
também forçará a execução imediata. Isso pode ser útil quando você deseja executar a consulta imediatamente e armazenar em cache os resultados. Para obter mais informações sobre esses métodos, consulte Converter tipos de dados.
Para obter mais informações sobre a execução da consulta, consulte Como gravar sua primeira consulta LINQ.
XML no Visual Basic
Os recursos XML no Visual Basic incluem literais XML e propriedades do eixo XML, que permitem criar, acessar, consultar e modificar XML facilmente em seu código. 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 subconjuntos 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, confira XML.
Recursos relacionados
Tópico | Descrição |
---|---|
XML | Descreve os recursos XML no Visual Basic que podem ser consultados e que permitem incluir XML como objetos de dados de primeira classe no código do Visual Basic. |
Consultas | Fornece informações de referência sobre as cláusulas de consulta disponíveis no Visual Basic. |
LINQ (Consulta Integrada à Linguagem) | Inclui informações gerais, diretrizes de programação e exemplos para LINQ. |
LINQ to SQL | Inclui informações gerais, diretrizes de programação e exemplos para LINQ to SQL. |
Objetos LINQ to | Inclui informações gerais, diretrizes de programação e exemplos para LINQ to Objects. |
LINQ to ADO.NET (página do portal) | Inclui links para informações gerais, diretrizes de programação e exemplos para LINQ to ADO.NET. |
LINQ to XML | Inclui informações gerais, diretrizes de programação e exemplos para LINQ to XML. |
Como 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 junções
Como classificar resultados de consulta
Como filtrar resultados de consulta
Como contar, somar ou fazer média de dados
Como localizar o valor mínimo ou máximo em um resultado de consulta
Capítulos do livro em destaque
Capítulo 17: LINQ na programação do Visual Basic 2008