Relações de tipo em operações de consulta (Visual Basic)

Variáveis usadas na LINQ (Consulta Integrada à Linguagem) consulta tem rigidez de tipos de operações e devem ser compatíveis entre si.Tipagem forte é usado na fonte de dados, a consulta em si e a execução da consulta.A ilustração a seguir identifica os termos usados para descrever um LINQ consulta.Para obter mais informações sobre as partes de uma consulta, consulte Operações básicas de consulta (Visual Basic).

Partes de uma consulta LINQ

Consulta de pseudocódigo com elementos realçados.

O tipo da variável de intervalo na consulta deve ser compatível com o tipo dos elementos na fonte de dados.O tipo da variável de consulta deve ser compatível com o elemento seqüência definido na Select cláusula.Finalmente, o tipo dos elementos seqüência também deve ser compatível com o tipo de variável de controle de loop é usado na For Each declaração que executa a consulta.Este tipagem forte facilita a identificação de erros de tipo em tempo de compilação.

Visual Basicconveniente forte digitando implementando inferência de tipo local, também conhecido como digitação implícita.Que recurso é usado no exemplo anterior, e você verá que ele é usado em todo o LINQ amostras e documentação.No Visual Basic, a inferência de tipo local é realizada simplesmente usando um Dim instrução sem um As cláusula.No exemplo a seguir, city tem rigidez de tipos como uma seqüência de caracteres.

Dim city = "Seattle"
ObservaçãoObservação

Inferência de tipo local só funciona quando Option Infer for definido como On.Para obter mais informações, consulte Declaração de Option Infer.

No entanto, mesmo que você use a inferência de tipo local em uma consulta, as mesmas relações de tipo estão presentes entre as variáveis na fonte de dados, a variável de consulta e o loop de execução da consulta.Ele é útil ter uma noção básica sobre essas relações de tipo, quando você está escrevendo LINQ consultas ou trabalhar com as amostras e exemplos de código na documentação.

Talvez você precise especificar um tipo explícito para uma variável de intervalo que não coincide com o tipo retornado da fonte de dados.Você pode especificar o tipo de variável de intervalo usando um As cláusula.No entanto, isso resulta em um erro se a conversão é um Estreitando conversão e Option Strict for definido como On.Portanto, recomendamos que você executar a conversão nos valores recuperados da fonte de dados.Você pode converter os valores da fonte de dados para o tipo de variável de intervalo explícito usando o Cast<TResult> método.Você também pode converter os valores selecionados na Select cláusula para um tipo explícito que seja diferente do tipo de variável de intervalo.Esses pontos são ilustrados no código a seguir.

Dim numbers1() As Integer = {1, 2, 4, 16, 32, 64}
Dim numbers2() As Double = {5.0#, 10.0#, 15.0#}

' This code does not result in an error.
Dim numberQuery1 = From n As Integer In numbers1 Where n > 5

' This code results in an error with Option Strict set to On. The type Double
' cannot be implicitly cast as type Integer.
Dim numberQuery2 = From n As Integer In numbers2 Where n > 5

' This code casts the values in the data source to type Integer. The type of
' the range variable is Integer.
Dim numberQuery3 = From n In numbers2.Cast(Of Integer)() Where n > 5

' This code returns the value of the range variable converted to Integer. The type of
' the range variable is Double.
Dim numberQuery4 = From n In numbers2 Where n > 5 Select CInt(n)

Consultas que retornam todo elementos dos dados de origem

A exemplo a seguir mostra um LINQ operação que retorna uma seqüência de elementos selecionados a partir dos dados de origem da consulta.A fonte, names, contém uma matriz de seqüências de caracteres, e a saída de consulta é uma seqüência contendo seqüências de caracteres que começam com a letra M.

Dim names = {"John", "Rick", "Maggie", "Mary"}
Dim mNames = From name In names
             Where name.IndexOf("M") = 0
             Select name

For Each nm In mNames
    Console.WriteLine(nm)
Next

Isso equivale ao código a seguir, mas é muito menor e mais fáceis de escrever.Dependência de inferência de tipo local nas consultas é o estilo preferencial em Visual Basic.

Dim names2 = {"John", "Rick", "Maggie", "Mary"}
Dim mNames2 As IEnumerable(Of String) =
    From name As String In names
    Where name.IndexOf("M") = 0
    Select name

For Each nm As String In mNames
    Console.WriteLine(nm)
Next

As seguintes relações existem em ambos os exemplos de código anterior, se os tipos são determinadas implicitamente ou explicitamente.

  1. O tipo dos elementos na fonte de dados, names, é o tipo de variável de intervalo, name, na consulta.

  2. O tipo do objeto selecionado, name, determina o tipo de variável de consulta, mNames.Aqui name é uma seqüência, para que a variável de consulta é IEnumerable (da seqüência de caracteres) em Visual Basic.

  3. A consulta definida na mNames é executado nos For Each loop.O loop itera sobre o resultado da execução da consulta.Porque mNames, quando ele é executado, retornará uma seqüência de seqüências de caracteres, a variável de iteração do loop, nm, também é uma seqüência de caracteres.

Consultas que retornam um campo a partir de elementos selecionados

A exemplo a seguir mostra um LINQ to SQL operação que retorna uma seqüência contendo apenas uma parte de cada elemento selecionado da fonte de dados de consulta.A consulta adota um conjunto de Customer objetos como fonte de dados e projetos somente o Name propriedade no resultado.Como o nome do cliente é uma seqüência de caracteres, a consulta produz uma seqüência de cadeias de caracteres como saída.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim custNames = From cust In customers 
                Where cust.City = "London" 
                Select cust.Name

For Each custName In custNames
    Console.WriteLine(custName)
Next

As relações entre as variáveis são como aqueles no exemplo mais simples.

  1. O tipo dos elementos na fonte de dados, customers, é o tipo de variável de intervalo, cust, na consulta.Neste exemplo, o que é do tipo Customer.

  2. O Select instrução retorna a Name propriedade de cada Customer objeto em vez de todo o objeto.Porque Name é uma seqüência, a variável de consulta, custNames, novamente será IEnumerable (Of String), não do Customer.

  3. Porque custNames representa uma seqüência de seqüências de caracteres, o For Each variável de iteração do loop, custName, deve ser uma seqüência.

Sem inferência de tipo local, o exemplo anterior seria mais complicado para escrever e entender, como mostra o exemplo a seguir.

' Method GetTable returns a table of Customer objects.
 Dim customers As Table(Of Customer) = db.GetTable(Of Customer)()
 Dim custNames As IEnumerable(Of String) = 
     From cust As Customer In customers 
     Where cust.City = "London" 
     Select cust.Name

 For Each custName As String In custNames
     Console.WriteLine(custName)
 Next

Consultas que exigem tipos anônimos

O exemplo a seguir mostra uma situação mais complexa.No exemplo anterior, era inconveniente especificar os tipos para todas as variáveis explicitamente.Neste exemplo, é impossível.Em vez de selecionar toda Customer elementos de fonte de dados ou um único campo de cada elemento, o Select cláusula nesta consulta retorna duas propriedades do original Customer objeto: Name e City.Em resposta para o Select cláusula, o compilador define um tipo anônimo que contém essas duas propriedades.O resultado da execução nameCityQuery na For Each loop é uma coleção de instâncias do novo tipo anônimo.Como o tipo anônimo não tem nenhum nome utilizável, você não pode especificar o tipo de nameCityQuery ou custInfo explicitamente.Ou seja, com um tipo anônimo, você não tem nenhum nome de tipo para usar no lugar de String na IEnumerable(Of String).Para obter mais informações, consulte Tipos anônimos (Visual Basic).

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim nameCityQuery = From cust In customers 
                    Where cust.City = "London" 
                    Select cust.Name, cust.City

For Each custInfo In nameCityQuery
    Console.WriteLine(custInfo.Name)
Next

Embora não seja possível especificar os tipos para todas as variáveis no exemplo anterior, os relacionamentos permanecem os mesmos.

  1. O tipo dos elementos na fonte de dados é, novamente, o tipo da variável de intervalo na consulta.Neste exemplo, cust é uma instância de Customer.

  2. Porque o Select instrução produz um tipo anônimo, a variável de consulta, nameCityQuery, devem ser digitadas implicitamente como um tipo anônimo.Um tipo anônimo sem nome utilizável e portanto não pode ser especificado explicitamente.

  3. O tipo da variável de iteração na For Each loop é o tipo anônimo, criado na etapa 2.Porque o tipo não tem nenhum nome utilizável, o tipo da variável de iteração de loop deve ser determinado implicitamente.

Consulte também

Conceitos

Tipos anônimos (Visual Basic)

Inferência de tipo de local (Visual Basic)

Introdução ao LINQ em Visual Basic

Outros recursos

Guia de Introdução do LINQ em Visual Basic

LINQ em Visual Basic

Consultas (Visual Basic)