Napište svůj první dotaz LINQ (Visual Basic)

Dotaz je výraz, který načítá data ze zdroje dat. Dotazy se vyjadřují ve vyhrazeném dotazovacím jazyce. V průběhu času byly vyvinuty různé jazyky pro různé typy zdrojů dat, například SQL pro relační databáze a XQuery pro XML. Vývojář aplikací tak potřebuje, aby se naučil nový dotazovací jazyk pro každý typ zdroje dat nebo formátu dat, který je podporovaný.

Jazykově integrovaný dotaz (LINQ) zjednodušuje situaci tím, že nabízí konsis režim stanu l pro práci s daty napříč různými druhy zdrojů a formátů dat. V dotazu LINQ vždy pracujete s objekty. Stejné základní vzory kódování použijete k dotazování a transformaci dat v dokumentech XML, databázích SQL, ADO.NET datových sadách a entitách, kolekcích rozhraní .NET Framework a všech dalších zdrojích nebo formátech, pro které je k dispozici poskytovatel LINQ. Tento dokument popisuje tři fáze vytváření a použití základních dotazů LINQ.

Tři fáze operace dotazu

Operace dotazu LINQ se skládají ze tří akcí:

  1. Získejte zdroj dat nebo zdroje.

  2. Vytvořte dotaz.

  3. Spusťte dotaz.

V LINQ se provádění dotazu liší od vytvoření dotazu. Nenačítáte žádná data pouze vytvořením dotazu. Tento bod je podrobněji popsán dále v tomto tématu.

Následující příklad znázorňuje tři části operace dotazu. Příklad používá pole celých čísel jako pohodlný zdroj dat pro demonstrační účely. Stejné koncepty se ale vztahují také na jiné zdroje dat.

Poznámka:

Na stránce kompilace návrhář projektu (Visual Basic) se ujistěte, že je odvozená možnost nastavena na Zapnuto.

' 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

Výstup:

0 2 4 6

Zdroj dat

Vzhledem k tomu, že zdroj dat v předchozím příkladu je pole, implicitně podporuje obecné IEnumerable<T> rozhraní. Je to skutečnost, že umožňuje použít pole jako zdroj dat pro dotaz LINQ. Typy, které podporují IEnumerable<T> nebo odvozené rozhraní, jako je obecný, IQueryable<T> se nazývají typy s možností dotazování.

Jako implicitně dotazovatelný typ nevyžaduje pole žádné úpravy ani speciální ošetření, které by sloužilo jako zdroj dat LINQ. Totéž platí pro všechny typy kolekcí, které podporují IEnumerable<T>, včetně obecného List<T>, Dictionary<TKey,TValue>a další třídy v knihovně tříd rozhraní .NET Framework.

Pokud zdrojová data ještě neimplementují IEnumerable<T>, zprostředkovatel LINQ je potřeba k implementaci funkcí standardních operátorů dotazu pro tento zdroj dat. Například LINQ to XML zpracovává práci načítání dokumentu XML do dotazovatelného XElement typu, jak je znázorněno v následujícím příkladu. Další informace o standardních operátorech dotazů naleznete v tématu Přehled standardních operátorů dotazů (Visual Basic).

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

Pomocí LINQ to SQL nejprve vytvoříte objektově relační mapování v době návrhu, a to buď ručně, nebo pomocí LINQ to SQL Tools v sadě Visual Studio v sadě Visual Studio. Zapisujete dotazy na objekty a v době běhu LINQ to SQL zpracovává komunikaci s databází. V následujícím příkladu customers představuje konkrétní tabulku v databázi a Table<TEntity> podporuje obecné 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)

Další informace o tom, jak vytvořit konkrétní typy zdrojů dat, najdete v dokumentaci pro různé poskytovatele LINQ. (Seznam těchto poskytovatelů najdete v tématu LINQ (jazykově integrovaný dotaz).) Základní pravidlo je jednoduché: zdroj dat LINQ je jakýkoli objekt, který podporuje obecné IEnumerable<T> rozhraní, nebo rozhraní, které z něj dědí.

Poznámka:

Jako zdroje dat LINQ lze použít také typy, jako ArrayList je například podpora ne generického IEnumerable rozhraní. Příklad, který používá ArrayList, viz Postupy: Dotazování ArrayList pomocí LINQ (Visual Basic).

Dotaz

V dotazu určíte, jaké informace chcete načíst ze zdroje nebo zdrojů dat. Máte také možnost určit, jak se mají tyto informace řadit, seskupit nebo strukturovat před vrácením. Aby bylo možné vytvořit dotaz, jazyk Visual Basic začlenil do jazyka novou syntaxi dotazu.

Při spuštění dotazu v následujícím příkladu vrátí všechna sudá čísla z celočíselného pole, 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

Výraz dotazu obsahuje tři klauzule: From, Wherea Select. Konkrétní funkce a účel každé klauzule výrazu dotazu je popsána v základních operacích dotazu (Visual Basic). Další informace najdete v tématu Dotazy. Všimněte si, že v LINQ se definice dotazu často ukládá do proměnné a spouští se později. Proměnná dotazu, například evensQuery v předchozím příkladu, musí být dotazovatelným typem. Typ evensQuery je IEnumerable(Of Integer)přiřazen kompilátorem pomocí odvození místního typu.

Je důležité si uvědomit, že samotná proměnná dotazu nevyžaduje žádnou akci a nevrací žádná data. Ukládá pouze definici dotazu. V předchozím příkladu se jedná o smyčku For Each , která provede dotaz.

Provádění dotazů

Provádění dotazů je oddělené od vytvoření dotazu. Vytvoření dotazu definuje dotaz, ale spuštění se aktivuje jiným mechanismem. Dotaz lze spustit hned, jak je definován (okamžité spuštění), nebo lze definici uložit a dotaz lze spustit později (odložené spuštění).

Odložené provedení

Typický dotaz LINQ se podobá dotazu v předchozím příkladu, ve kterém evensQuery je definovaný. Vytvoří dotaz, ale nespustí ho okamžitě. Místo toho je definice dotazu uložena v proměnné evensQuerydotazu . Dotaz spustíte později, obvykle pomocí For Each smyčky, která vrací posloupnost hodnot, nebo použitím standardního operátoru dotazu, například Count nebo Max. Tento proces se označuje jako odložené spuštění.

' 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()

Pro posloupnost hodnot získáte přístup k načteným datům pomocí proměnné iterace ve For Each smyčce (number v předchozím příkladu). Vzhledem k tomu, že proměnná dotazu obsahuje evensQuerydefinici dotazu místo výsledků dotazu, můžete dotaz spustit tak často, jak chcete, pomocí proměnné dotazu více než jednou. V aplikaci můžete mít například databázi, která se průběžně aktualizuje samostatnou aplikací. Po vytvoření dotazu, který načítá data z této databáze, můžete použít For Each smyčku k opakovanému spuštění dotazu a načtení nejnovějších dat pokaždé.

Následující příklad ukazuje, jak odložené spuštění funguje. Po evensQuery2 definování a spuštění smyčky For Each , jako v předchozích příkladech, se některé prvky ve zdroji numbers dat změní. Pak se znovu spustí evensQuery2 druhá For Each smyčka. Výsledky se liší podruhé, protože For Each smyčka provede dotaz znovu pomocí nových hodnot v 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()

Výstup:

Evens in original array:

0 2 4 6

Evens in changed array:

0 10 2 22 8

Okamžité provedení

Při odložené provádění dotazů se definice dotazu uloží do proměnné dotazu pro pozdější spuštění. Při okamžitém spuštění se dotaz spustí v době jeho definice. Spuštění se aktivuje, když použijete metodu, která vyžaduje přístup k jednotlivým prvkům výsledku dotazu. Okamžité spuštění je často vynuceno pomocí jednoho ze standardních operátorů dotazu, které vracejí jednotlivé hodnoty. Příklady jsou Count, , AverageMax, a First. Tyto standardní operátory dotazu spustí dotaz, jakmile se použijí k výpočtu a vrácení jednoho výsledku. Další informace o standardních operátorech dotazů, které vracejí jednotlivé hodnoty, naleznete v tématu Operace agregace, operace elementů a operace kvantifikátoru.

Následující dotaz vrátí počet sudých čísel v matici celých čísel. Definice dotazu není uložena a numEvens je jednoduchá Integer.

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

Stejný výsledek můžete dosáhnout pomocí Aggregate metody.

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

Spuštění dotazu můžete také vynutit voláním ToList nebo ToArray metodou dotazu (okamžité) nebo proměnné dotazu (odloženo), jak je znázorněno v následujícím kódu.

' 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()

V předchozích příkladech evensQuery3 je proměnná dotazu, ale evensList je to seznam a evensArray je pole.

Použití ToList nebo ToArray vynucení okamžitého spuštění je zvlášť užitečné ve scénářích, ve kterých chcete spustit dotaz okamžitě a uložit výsledky do mezipaměti v jednom objektu kolekce. Další informace o těchto metodách naleznete v tématu Převod datových typů.

Dotaz můžete také spustit pomocí IEnumerable metody, jako IEnumerable.GetEnumerator je metoda.

Viz také