Dela via


Skriva din första LINQ-fråga (Visual Basic)

En fråga är ett uttryck som hämtar data från en datakälla. Frågor uttrycks i ett dedikerat frågespråk. Med tiden har olika språk utvecklats för olika typer av datakällor, till exempel SQL för relationsdatabaser och XQuery för XML. Detta gör det nödvändigt för programutvecklaren att lära sig ett nytt frågespråk för varje typ av datakälla eller dataformat som stöds.

Språkintegrerad fråga (LINQ) förenklar situationen genom att erbjuda en consis tältläge l för att arbeta med data över olika typer av datakällor och format. I en LINQ-fråga arbetar du alltid med objekt. Du använder samma grundläggande kodningsmönster för att fråga och transformera data i XML-dokument, SQL-databaser, ADO.NET datauppsättningar och entiteter, .NET Framework-samlingar och andra källor eller format som en LINQ-provider är tillgänglig för. Det här dokumentet beskriver de tre faserna i skapandet och användningen av grundläggande LINQ-frågor.

Tre steg i en frågeåtgärd

LINQ-frågeåtgärder består av tre åtgärder:

  1. Hämta datakällan eller källorna.

  2. Skapa frågan.

  3. Kör frågan.

I LINQ skiljer sig körningen av en fråga från skapandet av frågan. Du hämtar inte några data bara genom att skapa en fråga. Den här punkten beskrivs mer detaljerat senare i det här avsnittet.

I följande exempel visas de tre delarna i en frågeåtgärd. I exemplet används en matris med heltal som en praktisk datakälla i demonstrationssyfte. Samma begrepp gäller dock även för andra datakällor.

Kommentar

På kompileringssidan , Projektdesigner (Visual Basic), kontrollerar du att Alternativ härledning är inställt på På.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

Utdata:

0 2 4 6

Datakällan

Eftersom datakällan i föregående exempel är en matris stöder den implicit det allmänna IEnumerable<T> gränssnittet. Det är detta faktum som gör att du kan använda en matris som datakälla för en LINQ-fråga. Typer som stöder IEnumerable<T> eller ett härlett gränssnitt, till exempel det generiska IQueryable<T> , kallas frågebara typer.

Som en implicit frågebar typ kräver matrisen ingen ändring eller särskild behandling för att fungera som en LINQ-datakälla. Detsamma gäller för alla samlingstyper som stöder IEnumerable<T>, inklusive generiska List<T>, Dictionary<TKey,TValue>och andra klasser i .NET Framework-klassbiblioteket.

Om källdata inte redan implementerar IEnumerable<T>behövs en LINQ-provider för att implementera funktionerna hos standardfrågaoperatorerna för datakällan. LINQ till XML hanterar till exempel arbetet med att läsa in ett XML-dokument i en frågebar XElement typ, som du ser i följande exempel. Mer information om vanliga frågeoperatorer finns i Översikt över vanliga frågeoperatorer (Visual Basic).

' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")

Med LINQ till SQL skapar du först en objektrelationsmappning vid designtillfället, antingen manuellt eller med hjälp av LINQ till SQL Tools i Visual Studio i Visual Studio. Du skriver dina frågor mot objekten och vid körning hanterar LINQ till SQL kommunikationen med databasen. I följande exempel customers representerar en specifik tabell i databasen och Table<TEntity> har stöd för generiska IQueryable<T>.

' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)

Mer information om hur du skapar specifika typer av datakällor finns i dokumentationen för de olika LINQ-leverantörerna. (En lista över dessa leverantörer finns i LINQ (Language-Integrated Query).) Den grundläggande regeln är enkel: en LINQ-datakälla är ett objekt som stöder det allmänna IEnumerable<T> gränssnittet eller ett gränssnitt som ärver från det.

Kommentar

Typer som ArrayList dessa stöder det icke-generiska IEnumerable gränssnittet kan också användas som LINQ-datakällor. Ett exempel som använder en ArrayListfinns i How to: Query an ArrayList with LINQ (Visual Basic).

Frågan

I frågan anger du vilken information du vill hämta från datakällan eller källorna. Du kan också ange hur informationen ska sorteras, grupperas eller struktureras innan den returneras. För att skapa frågor har Visual Basic införlivat ny frågesyntax i språket.

När den körs returnerar frågan i följande exempel alla jämna tal från en heltalsmatris, numbers.

' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}

' Query creation.
Dim evensQuery = From num In numbers
                 Where num Mod 2 = 0
                 Select num

' Query execution.
For Each number In evensQuery
    Console.Write(number & " ")
Next

Frågeuttrycket innehåller tre satser: From, Whereoch Select. Den specifika funktionen och syftet med varje frågeuttryckssats beskrivs i Grundläggande frågeåtgärder (Visual Basic). Mer information finns i Frågor. Observera att i LINQ lagras ofta en frågedefinition i en variabel och körs senare. Frågevariabeln, till exempel evensQuery i föregående exempel, måste vara en frågetyp. Typen är evensQueryIEnumerable(Of Integer), tilldelad av kompilatorn med hjälp av lokal typinferens.

Det är viktigt att komma ihåg att själva frågevariabeln inte vidtar någon åtgärd och inte returnerar några data. Den lagrar bara frågedefinitionen. I föregående exempel är det loopen For Each som kör frågan.

Frågekörning

Frågekörning är separat från skapande av frågor. Frågeskapande definierar frågan, men körningen utlöses av en annan mekanism. En fråga kan köras så snart den har definierats (omedelbar körning) eller så kan definitionen lagras och frågan kan köras senare (uppskjuten körning).

Uppskjuten körning

En typisk LINQ-fråga liknar den i föregående exempel, där evensQuery definieras. Den skapar frågan men kör den inte omedelbart. I stället lagras frågedefinitionen i frågevariabeln evensQuery. Du kör frågan senare, vanligtvis med hjälp av en For Each loop, som returnerar en sekvens med värden eller genom att använda en standardfrågaoperator, till exempel Count eller Max. Den här processen kallas för uppskjuten körning.

' Query execution that results in a sequence of values.
For Each number In evensQuery
    Console.Write(number & " ")
Next

' Query execution that results in a single value.
Dim evens = evensQuery.Count()

För en sekvens med värden får du åtkomst till hämtade data med hjälp av iterationsvariabeln i loopen For Each (number i föregående exempel). Eftersom frågevariabeln , evensQueryinnehåller frågedefinitionen i stället för frågeresultatet, kan du köra en fråga så ofta du vill genom att använda frågevariabeln mer än en gång. Du kan till exempel ha en databas i ditt program som uppdateras kontinuerligt av ett separat program. När du har skapat en fråga som hämtar data från databasen kan du använda en For Each loop för att köra frågan upprepade gånger och hämta de senaste data varje gång.

I följande exempel visas hur uppskjuten körning fungerar. När evensQuery2 har definierats och körts med en For Each loop, som i föregående exempel, ändras vissa element i datakällan numbers . Sedan körs evensQuery2 en andra For Each loop igen. Resultatet skiljer sig andra gången, eftersom loopen For Each kör frågan igen med hjälp av de nya värdena i numbers.

Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}

Dim evensQuery2 = From num In numberArray
                  Where num Mod 2 = 0
                  Select num

Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8

' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
    Console.Write("  " & number)
Next
Console.WriteLine()

Utdata:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

Omedelbar körning

Vid uppskjuten körning av frågor lagras frågedefinitionen i en frågevariabel för senare körning. Vid omedelbar körning körs frågan vid tidpunkten för definitionen. Körning utlöses när du använder en metod som kräver åtkomst till enskilda element i frågeresultatet. Omedelbar körning tvingas ofta med hjälp av en av de vanliga frågeoperatorer som returnerar enkla värden. Exempel är Count, Max, Averageoch First. Dessa standardfrågeoperatorer kör frågan så snart de tillämpas för att beräkna och returnera ett singleton-resultat. Mer information om vanliga frågeoperatorer som returnerar enkla värden finns i Aggregeringsåtgärder, elementåtgärder och kvantifieraråtgärder.

Följande fråga returnerar ett antal jämna tal i en matris med heltal. Frågedefinitionen sparas inte och numEvens är en enkel Integer.

Dim numEvens = (From num In numbers
                Where num Mod 2 = 0
                Select num).Count()

Du kan uppnå samma resultat med hjälp Aggregate av metoden .

Dim numEvensAgg = Aggregate num In numbers
                  Where num Mod 2 = 0
                  Select num
                  Into Count()

Du kan också framtvinga körning av en fråga genom att anropa ToList metoden eller ToArray på en fråga (omedelbar) eller frågevariabel (uppskjuten), enligt följande kod.

' Immediate execution.
Dim evensList = (From num In numbers
                 Where num Mod 2 = 0
                 Select num).ToList()

' Deferred execution.
Dim evensQuery3 = From num In numbers
                  Where num Mod 2 = 0
                  Select num
' . . .
Dim evensArray = evensQuery3.ToArray()

I föregående exempel evensQuery3 är en frågevariabel, men evensList är en lista och evensArray är en matris.

Att använda ToList eller ToArray framtvinga omedelbar körning är särskilt användbart i scenarier där du vill köra frågan omedelbart och cachelagra resultatet i ett enda samlingsobjekt. Mer information om dessa metoder finns i Konvertera datatyper.

Du kan också orsaka att en fråga körs med hjälp av en IEnumerable metod som IEnumerable.GetEnumerator metoden.

Se även