Delen via


Relaties typen in querybewerkingen (Visual Basic)

Variabelen die worden gebruikt in LINQ-querybewerkingen (Language-Integrated Query) zijn sterk getypt en moeten compatibel zijn met elkaar. Sterk typen wordt gebruikt in de gegevensbron, in de query zelf en in de uitvoering van de query. In de volgende afbeelding ziet u termen die worden gebruikt om een LINQ-query te beschrijven. Zie Basic Query Operations (Visual Basic) voor meer informatie over de onderdelen van een query.

Screenshot showing a pseudocode query with elements highlighted.

Het type bereikvariabele in de query moet compatibel zijn met het type elementen in de gegevensbron. Het type van de queryvariabele moet compatibel zijn met het reekselement dat in de Select component is gedefinieerd. Ten slotte moet het type van de reekselementen ook compatibel zijn met het type lusbesturingsvariabele dat wordt gebruikt in de For Each instructie waarmee de query wordt uitgevoerd. Deze sterke typen vergemakkelijkt het identificeren van typefouten tijdens het compileren.

Visual Basic maakt sterk typen handig door het implementeren van lokale typedeductie, ook wel impliciet typen genoemd. Deze functie wordt gebruikt in het vorige voorbeeld en u ziet dat deze wordt gebruikt in de LINQ-voorbeelden en -documentatie. In Visual Basic wordt deductie van het lokale type eenvoudig uitgevoerd met behulp van een Dim instructie zonder een As component. In het volgende voorbeeld city wordt sterk getypt als een tekenreeks.

Dim city = "Seattle"

Notitie

Deductie van het lokale type werkt alleen als Option Infer deze is ingesteld op On. Zie Option Infer Statement voor meer informatie.

Zelfs als u lokale typedeductie in een query gebruikt, zijn dezelfde typerelaties aanwezig onder de variabelen in de gegevensbron, de queryvariabele en de uitvoeringslus van de query. Het is handig om basiskennis te hebben van deze typerelaties bij het schrijven van LINQ-query's of het werken met de voorbeelden en codevoorbeelden in de documentatie.

Mogelijk moet u een expliciet type opgeven voor een bereikvariabele die niet overeenkomt met het type dat wordt geretourneerd uit de gegevensbron. U kunt het type bereikvariabele opgeven met behulp van een As component. Dit resulteert echter in een fout als de conversie een smalle conversie is en Option Strict is ingesteld op On. Daarom raden we u aan om de conversie uit te voeren op de waarden die zijn opgehaald uit de gegevensbron. U kunt de waarden van de gegevensbron converteren naar het type expliciete bereikvariabele met behulp van de Cast methode. U kunt de waarden die in de Select component zijn geselecteerd ook casten naar een expliciet type dat verschilt van het type bereikvariabele. Deze punten worden geïllustreerd in de volgende code.

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)

Query's die volledige elementen van de brongegevens retourneren

In het volgende voorbeeld ziet u een LINQ-querybewerking die een reeks elementen retourneert die zijn geselecteerd op basis van de brongegevens. De bron, namesbevat een matrix met tekenreeksen en de queryuitvoer is een reeks met tekenreeksen die beginnen met de letter 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

Dit komt overeen met de volgende code, maar is veel korter en eenvoudiger te schrijven. Afhankelijk van lokale typedeductie in query's is de voorkeursstijl in 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

De volgende relaties bestaan in beide van de vorige codevoorbeelden, ongeacht of de typen impliciet of expliciet worden bepaald.

  1. Het type elementen in de gegevensbron, namesis het type bereikvariabele, namein de query.

  2. Het type object dat is geselecteerd, namebepaalt het type van de queryvariabele. mNames Hier name volgt een tekenreeks, dus de queryvariabele is IEnumerable(Of String) in Visual Basic.

  3. De query die is gedefinieerd, mNames wordt uitgevoerd in de For Each lus. De lus doorloopt het resultaat van het uitvoeren van de query. Omdat mNames, wanneer deze wordt uitgevoerd, een reeks tekenreeksen retourneert, is de lusiteratievariabele ook nmeen tekenreeks.

Query's die één veld retourneren van geselecteerde elementen

In het volgende voorbeeld ziet u een LINQ-naar-SQL-querybewerking die een reeks retourneert die slechts één deel van elk element bevat dat is geselecteerd uit de gegevensbron. De query gebruikt een verzameling Customer objecten als gegevensbron en projecteert alleen de Name eigenschap in het resultaat. Omdat de naam van de klant een tekenreeks is, produceert de query een reeks tekenreeksen als uitvoer.

' 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

De relaties tussen variabelen zijn vergelijkbaar met die in het eenvoudigere voorbeeld.

  1. Het type elementen in de gegevensbron, customersis het type bereikvariabele, custin de query. In dit voorbeeld is Customerdat type .

  2. De Select instructie retourneert de Name eigenschap van elk Customer object in plaats van het hele object. Omdat Name dit een tekenreeks is, is de queryvariabele, custNamesopnieuw IEnumerable(Of String), niet van Customer.

  3. Omdat custNames dit een reeks tekenreeksen vertegenwoordigt, moet de herhalingsvariabele van custNamede For Each lus een tekenreeks zijn.

Zonder lokale typedeductie zou het vorige voorbeeld lastiger zijn om te schrijven en te begrijpen, zoals in het volgende voorbeeld wordt weergegeven.

' 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

Query's waarvoor anonieme typen zijn vereist

In het volgende voorbeeld ziet u een complexere situatie. In het vorige voorbeeld was het lastig om typen voor alle variabelen expliciet op te geven. In dit voorbeeld is het onmogelijk. In plaats van volledige Customer elementen uit de gegevensbron of één veld van elk element te selecteren, retourneert de Select component in deze query twee eigenschappen van het oorspronkelijke Customer object: Name en City. Als reactie op de Select component definieert de compiler een anoniem type dat deze twee eigenschappen bevat. Het resultaat van het uitvoeren nameCityQuery in de For Each lus is een verzameling exemplaren van het nieuwe anonieme type. Omdat het anonieme type geen bruikbare naam heeft, kunt u het type of nameCityQuerycustInfo expliciet niet opgeven. Dat wil gezegd dat u met een anoniem type geen typenaam hebt om te gebruiken in plaats van String in IEnumerable(Of String). Zie Anonieme typen voor meer informatie.

' 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

Hoewel het niet mogelijk is om typen op te geven voor alle variabelen in het vorige voorbeeld, blijven de relaties hetzelfde.

  1. Het type elementen in de gegevensbron is opnieuw het type bereikvariabele in de query. In dit voorbeeld cust is dit een instantie van Customer.

  2. Omdat de Select instructie een anoniem type produceert, moet de queryvariabele impliciet nameCityQueryworden getypt als een anoniem type. Een anoniem type heeft geen bruikbare naam en kan daarom niet expliciet worden opgegeven.

  3. Het type iteratievariabele in de For Each lus is het anonieme type dat in stap 2 is gemaakt. Omdat het type geen bruikbare naam heeft, moet het type lusiteratievariabele impliciet worden bepaald.

Zie ook