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í:
Získejte zdroj dat nebo zdroje.
Vytvořte dotaz.
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
, Where
a 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é evensQuery
dotazu . 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 evensQuery
definici 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
, , Average
Max
, 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.