Sdílet prostřednictvím


Úvod do dotazů LINQ (C#)

Dotaz je výraz, který načte data ze zdroje dat.Dotazy jsou obvykle vyjádřeny v 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.Vývojáři se proto musí naučit nový jazyk dotazu pro každý typ zdroje dat nebo formátu dat, který musí podporovat.LINQ tuto situaci zjednodušuje tím, že nabízí konzistentní model pro práci s daty napříč různými druhy datových zdrojů a formátů.V dotazu LINQ vždy pracujete s objekty.Stejné základní vzorce kódování používáte k dotazování a transformaci dat v dokumentech XML, databázích SQL, datových sadách ADO.NET, 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 dotazu LINQ se skládají ze tří různých akcí:

  1. Získejte zdroj dat.

  2. Vytvořte dotaz.

  3. Proveďte dotaz.

Následující příklad ukazuje, jak tyto tři části operace dotazu jsou vyjádřeny ve zdrojovém kódu.V příkladu se pro pohodlí používá celočíselné pole jako zdroj dat. Nicméně stejný koncept platí také pro další zdroje dat.Na tento příklad se odkazuje ve 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);
        }
    }
}

Následující ilustrace znázorňuje operaci úplného dotazu.V LINQ se provádění dotazu liší od samotného dotazu; jinými slovy nebyla načtena žádná data pouhým vytvořením proměnné dotazu.

Dokončení operace dotazu LINQ

Zdroj dat

Protože je v předchozím příkladu zdrojem dat pole, implicitně podporuje obecné rozhraní IEnumerable.Tato skutečnost znamená, že může být dotázán pomocí LINQ.Dotaz je proveden v příkazu foreach, a foreach vyžaduje IEnumerable nebo IEnumerable.Typy, které podporují IEnumerable nebo odvozené rozhraní, jako je obecný IQueryable, se nazývají dotazovatelné typy.

Dotazovatelný typ vyžaduje žádné změny nebo zvláštní zacházení jako zdroj dat LINQ.Pokud zdroj dat již není v paměti jako dotazovatelný typ, poskytovatel LINQ ho musí představovat jako takový.Například Technologie LINQ to XML načte dokument XML do dotazovatelného typu XElement:

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

S Technologie LINQ to SQL, nejprve vytvoříte mapování vázané na objekt v době návrhu ručně nebo pomocí Object Relational Designer (O/R Designer).Dotazy zapisujete proti objektům a v době běhu Technologie LINQ to SQL zpracovává komunikaci s databází.V následujícím příkladu představuje Customers určitou tabulku v databázi a typ výsledku dotazu IQueryable, který je odvozen z IEnumerable.

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 postupu vytváření určitých typů zdrojů dat naleznete v dokumentaci pro různé poskytovatele LINQ.Základní pravidlo je však velmi jednoduché: Zdroj dat služby LINQ je libovolný objekt, který podporuje obecné rozhraní IEnumerable nebo rozhraní, které z něj dědí.

[!POZNÁMKA]

Typy, jako je ArrayList podporující neobecné rozhraní IEnumerable, lze použít také jako zdroj dat LINQ.Další informace naleznete v tématu Postupy: Vytvoření dotazu na ArrayList pomocí LINQ.

Dotaz

Dotaz určuje, jaké informace se mají načíst z datového zdroje nebo zdrojů.V případě potřeby dotaz také určuje, jak by tyto informace měly být seřazeny, seskupeny a tvarovány dříve, než jsou vráceny.Dotaz je uložen v proměnné dotazu a inicializován pomocí výrazu dotazu.Chcete-li usnadnit psaní dotazů, jazyk C# zavedl novou syntaxi dotazu.

Dotaz v předchozím příkladu vrátí všechna sudá čísla z pole celých čísel.Výraz dotazu obsahuje tři věty: from, where a select. (Pokud jste obeznámeni s SQL, všimnete si, že pořadí klauzulí je ve srovnání v pořadím SQL obrácené.) Klauzule from určuje zdroj dat, klauzule where aplikuje filtr a klauzule select určuje typ vrácených prvků.Tyto a další klauzule dotazu jsou podrobně popsány v oddílu LINQ – výrazy dotazů (Průvodce programováním v C#).Prozatím je důležité, že ve službě LINQ dotaz sám o sobě neprovede žádnou akci a nevrátí žádná data.Ukládá pouze informace nutné pro vytvoření výsledku při spuštění dotazu někdy později.Další informace o tom, jak jsou dotazy konstruovány na pozadí, naleznete v tématu Přehled standardních operátorů dotazu.

[!POZNÁMKA]

Dotazy lze také vyjádřit pomocí syntaxe metody.Další informace naleznete v tématu Syntaxe využívající dotazy a syntaxe využívající metody v jazyce LINQ (C#).

Provádění dotazů

Odložené provedení

Jak bylo uvedeno dříve, proměnná dotazu sama ukládá pouze příkazy dotazu.Aktuální provádění dotazu je odloženo, dokud neprovedete iteraci v proměnné dotazu v prohlášení foreach.Tento koncept se nazývá 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);
}

Prohlášení foreach je také místo, ze kterého jsou získávány výsledky dotazu.Například v předchozím dotazu proměnná iterace num obsahuje všechny hodnoty (po jedné) ve vrácené posloupnosti.

Vzhledem k tomu, že proměnné dotazu samy nikdy neobsahují výsledky dotazu, můžete je spustit tak často, jak potřebujete.Například můžete mít databázi, která se průběžně aktualizuje pomocí samostatné aplikace.V aplikaci můžete vytvořit jeden dotaz, který načítá aktuální data a můžete jej také v některých intervalech spustit opakovaně a získat tak pokaždé jiné výsledky.

Vynucení okamžitého provedení

Dotazy, které provádějí funkce agregace v rozsahu prvků zdroje, musí nejprve provést v těchto prvcích iteraci.Příklady takových dotazů jsou Count, Max, Average a First.Provádějí se bez explicitního příkazu foreach, protože samotný dotaz musí používat foreach k vrácení výsledku.Všimněte si také, že tyto typy dotazů vrací pouze jednu hodnotu, nikoli kolekci IEnumerable.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é spuštění libovolného dotazu a uložit jeho výsledky do mezipaměti, můžete volat metody ToList``1 nebo ToArray``1.

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 spuštění vložením smyčky foreach ihned za výraz dotazu.Nicméně volání ToList nebo ToArray také uloží všechna data do mezipaměti jednoho objektu kolekce.

Viz také

Úkoly

Návod: Zápis dotazů v C# (LINQ)

Ukázky LINQ

Referenční dokumentace

foreach, in (Referenční dokumentace jazyka C#)

Koncepty

O/R Designer Overview

LINQ – výrazy dotazů (Průvodce programováním v C#)

Další zdroje

Začínáme s dotazy LINQ v jazyce C#

Klíčová slova dotazu (Referenční dokumentace jazyka C#)

Video – LINQ a odložené spuštění