Úvod do dotazů LINQ (C#)

Dotaz je výraz, který načítá data ze zdroje dat. Dotazy jsou obvykle vyjádřeny ve specializovaném dotazovacím jazyce. různé jazyky byly vyvinuty v průběhu času pro různé typy zdrojů dat, například SQL pro relační databáze a XQuery pro XML. Proto se vývojářům musel naučit nový dotazovací jazyk pro každý typ zdroje dat nebo formátu dat, který musí podporovat. LINQ tuto situaci zjednodušuje tím, že nabízí jednotný model pro práci s daty napříč různými druhy datových zdrojů a formátů. V dotazu LINQ budete vždy pracovat s objekty. použijete stejné základní vzory kódování pro dotazování a transformaci dat v dokumentech XML, SQL databázích, ADO.NET datových sadách, kolekcích .net a jakémkoli jiném formátu, pro který je k dispozici poskytovatel LINQ.

Tři části operace dotazu

Všechny operace dotazů LINQ se skládají ze tří různých akcí:

  1. Získání zdroje dat.

  2. Vytvořte dotaz.

  3. Spusťte dotaz.

Následující příklad ukazuje, jak jsou tři části operace dotazu vyjádřeny ve zdrojovém kódu. Příklad používá celočíselné pole jako zdroj dat pro usnadnění práce; stejné koncepty se však vztahují i na jiné zdroje dat. Tento příklad je odkazován v celém zbývající části tohoto tématu.

class IntroToLINQ
{
    static void Main()
    {
        // The Three Parts of a LINQ Query:
        // 1. Data source.
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

        // 2. Query creation.
        // numQuery is an IEnumerable<int>
        var numQuery =
            from num in numbers
            where (num % 2) == 0
            select num;

        // 3. Query execution.
        foreach (int num in numQuery)
        {
            Console.Write("{0,1} ", num);
        }
    }
}

Na následujícím obrázku vidíte kompletní operaci dotazování. V LINQ je spuštění dotazu odlišné od samotného dotazu. Jinými slovy, nenačtete žádná data pouhým vytvořením proměnné dotazu.

Diagram úplné operace dotazu LINQ

Zdroj dat

Protože zdroj dat v předchozím příkladu je pole, implicitně podporuje obecné IEnumerable<T> rozhraní. Tato skutečnost znamená, že se dá dotazovat pomocí LINQ. Dotaz je spuštěn v foreach příkazu a foreach vyžaduje IEnumerable nebo IEnumerable<T> . Typy, které podporují IEnumerable<T> nebo odvozené rozhraní, jako je například obecné, IQueryable<T> se nazývají Queryable typy.

Typ Queryable nevyžaduje žádnou úpravu ani zvláštní úpravu, aby sloužil jako zdroj dat LINQ. Pokud zdrojová data ještě nejsou v paměti jako Queryable typ, poskytovatel LINQ ho musí představovat jako takový. například LINQ to XML načte dokument XML do XElement typu queryable:

// Create a data source from an XML document.
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");

pomocí Technologie LINQ to SQL nástroje nejprve vytvoříte mapování relačních objektů v době návrhu buď ručně, nebo pomocí LINQ to SQLch nástrojů v Visual Studio. Zapisujete dotazy na objekty a v době běhu Technologie LINQ to SQL zpracovává komunikaci s databází. V následujícím příkladu Customers představuje určitou tabulku v databázi a typ výsledku dotazu, který je IQueryable<T> odvozen z IEnumerable<T> .

Northwnd db = new Northwnd(@"c:\northwnd.mdf");

// Query for customers in London.
IQueryable<Customer> custQuery =
    from cust in db.Customers
    where cust.City == "London"
    select cust;

Další informace o tom, jak vytvořit konkrétní typy zdrojů dat, naleznete v dokumentaci pro různé zprostředkovatele LINQ. Základní pravidlo je však velmi jednoduché: zdrojem dat LINQ je libovolný objekt, který podporuje obecné IEnumerable<T> rozhraní nebo rozhraní, které z něj dědí.

Poznámka

Typy, jako je například ArrayList Podpora neobecného IEnumerable rozhraní, lze použít také jako zdroj dat LINQ. Další informace najdete v tématu Postup dotazování objektu ArrayList pomocí LINQ (C#).

Dotaz

Dotaz určuje, jaké informace se mají načíst ze zdroje dat nebo zdrojů. V případě potřeby dotaz také určuje, jak se mají tyto informace seřadit, seskupit a tvarovat před tím, než se vrátí. Dotaz je uložen v proměnné dotazu a inicializován pomocí výrazu dotazu. Pro snazší zápis dotazů zavedl jazyk C# novou syntaxi dotazu.

Dotaz v předchozím příkladu vrátí všechna sudá čísla z pole Integer. Výraz dotazu obsahuje tři klauzule: from where a select . (pokud jste obeznámeni s SQL, jste si všimli, že řazení klauzulí se obrátí z pořadí v SQL.) fromKlauzule určuje zdroj dat, where klauzule aplikuje filtr a select klauzule určuje typ vrácených prvků. Tyto a další klauzule dotazu jsou podrobně popsány v oddílu LINQ (Language Integrated Query) . V současnosti je důležité, že v jazyce LINQ proměnná dotazu sám neprovede žádnou akci a nevrátí žádná data. Pouze ukládá informace, které jsou požadovány k vyprodukování výsledků při spuštění dotazu v pozdějším okamžiku. Další informace o tom, jak jsou dotazy vytvářeny na pozadí, najdete v tématu Přehled standardních operátorů dotazu (C#).

Poznámka

Dotazy lze také vyjádřit pomocí syntaxe metody. Další informace naleznete v tématu syntaxe dotazu a syntaxe metody v jazyce LINQ.

Provádění dotazů

Odložené provedení

Jak bylo uvedeno dříve, proměnná dotazu sama ukládá pouze příkazy dotazu. Skutečné provedení dotazu je odloženo, dokud neprovedete iteraci nad proměnnou dotazu v foreach příkazu. Tento koncept se označuje jako odložené provedení a je znázorněn v následujícím příkladu:

//  Query execution.
foreach (int num in numQuery)
{
    Console.Write("{0,1} ", num);
}

foreachPříkaz je také místo, kde jsou načteny výsledky dotazu. Například v předchozím dotazu proměnná iterace num uchovává každou hodnotu (jednu v čase) ve vrácené sekvenci.

Vzhledem k tomu, že proměnná dotazu sama o sobě nemá výsledky dotazu, můžete ji spustit tak často, jak chcete. Můžete mít například databázi, která je průběžně aktualizována samostatnou aplikací. V aplikaci můžete vytvořit jeden dotaz, který načte nejnovější data, a můžete ho spustit opakovaně v určitém intervalu, abyste pokaždé získali různé výsledky.

Vynucení okamžitého provedení

Dotazy, které provádějí agregační funkce v rozsahu zdrojových elementů, musí nejprve iterovat přes tyto prvky. Příklady takových dotazů jsou Count , Max , Average a First . Tyto příkazy jsou spouštěny bez explicitního foreach příkazu, protože samotný dotaz musí použít foreach , aby mohl vracet výsledek. Všimněte si také, že tyto typy dotazů vracejí jednu hodnotu, nikoli IEnumerable kolekci. Následující dotaz vrátí počet sudých čísel ve zdrojovém poli:

var evenNumQuery =
    from num in numbers
    where (num % 2) == 0
    select num;

int evenNumCount = evenNumQuery.Count();

Chcete-li vynutit okamžité provedení jakýchkoli dotazů a uložit výsledky do mezipaměti, můžete ToList volat ToArray metody nebo.

List<int> numQuery2 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToList();

// or like this:
// numQuery3 is still an int[]

var numQuery3 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToArray();

Můžete také vynutit provádění vložením foreach smyčky hned za výraz dotazu. Nicméně voláním ToList nebo ToArray také ukládáte do mezipaměti všechna data v jediném objektu kolekce.

Viz také