Syntaxe využívající dotazy a syntaxe využívající metody v jazyce LINQ (C#)

Většina dotazů v úvodní dokumentaci k LINQ (Language Integrated Query) se píše pomocí syntaxe deklarativních dotazů LINQ. Syntaxe dotazu však musí být při kompilaci kódu přeložena na volání metody modulu CLR (Common Language Runtime) technologie .NET. Volání těchto metod vyvolat standardní operátory dotazu, které mají názvy jako Where , , , , a Select GroupBy Join Max Average . Můžete je volat přímo pomocí syntaxe metody místo syntaxe dotazu.

Syntaxe dotazů a syntaxe metod jsou sémanticky identické, ale pro mnoho lidí je syntaxe dotazů jednodušší a snadněji čitelný. Některé dotazy musí být vyjádřeny jako volání metod. Například je nutné použít volání metody k vyjádření dotazu, který načte počet prvků, které odpovídají zadané podměně. Musíte také použít volání metody pro dotaz, který načte prvek, který má maximální hodnotu ve zdrojové sekvenci. Referenční dokumentace pro standardní operátory dotazů v oboru názvů System.Linq obecně používá syntaxi metody. Proto i v případě, že začínáte psát dotazy LINQ, je užitečné se seznámit s tím, jak používat syntaxi metod v dotazech a ve výrazech dotazů.

Metody rozšíření standardních operátorů dotazů

Následující příklad ukazuje jednoduchý výraz dotazu a sémanticky ekvivalentní dotaz napsaný jako dotaz založený na metodě.

class QueryVMethodSyntax
{
    static void Main()
    {
        int[] numbers = { 5, 10, 8, 3, 6, 12};

        //Query syntax:
        IEnumerable<int> numQuery1 =
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;

        //Method syntax:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

        foreach (int i in numQuery1)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine(System.Environment.NewLine);
        foreach (int i in numQuery2)
        {
            Console.Write(i + " ");
        }

        // Keep the console open in debug mode.
        Console.WriteLine(System.Environment.NewLine);
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/*
    Output:
    6 8 10 12
    6 8 10 12
 */

Výstup z těchto dvou příkladů je identický. Vidíte, že typ proměnné dotazu je stejný v obou formách: IEnumerable<T> .

Pokud chcete porozumět dotazu založeném na metodě, podívejme se na něj pečlivěji. Na pravé straně výrazu si všimněte, že klauzule je nyní vyjádřena jako metoda instance objektu , která, jak si vzpomenete, where numbers má typ IEnumerable<int> . Pokud jste obeznámeni s obecným IEnumerable<T> rozhraním, víte, že nemá Where metodu . Pokud ale vyvoláte seznam doplňování IntelliSense v integrovaném vývojovém Visual Studio ideu technologie Visual Studio, uvidíte nejen metodu, ale také řadu dalších metod, jako jsou , , a Where Select SelectMany Join Orderby . Všechny jsou to standardní operátory dotazů.

Snímek obrazovky zobrazující všechny standardní operátory dotazu v IntelliSense

I když to vypadá, jako by byly tyto další metody znovu definovány, ve skutečnosti tomu IEnumerable<T> tak není. Standardní operátory dotazů jsou implementovány jako nový druh metody nazývaný rozšiřující metody. Metody rozšíření "rozšiřují" existující typ. Mohou být volány, jako by to byly metody instance typu. Standardní operátory dotazu IEnumerable<T> rozšiřují a proto můžete psát numbers.Where(...) .

Pokud chcete začít používat LINQ, musíte o metodách rozšíření vědět jen to, jak je přenést do oboru ve vaší aplikaci pomocí správných using direktiv. Z pohledu vaší aplikace je metoda rozšíření a metoda běžné instance stejné.

Další informace o rozšiřujících metodách najdete v tématu Metody rozšíření. Další informace o standardních operátorech dotazů najdete v tématu Přehled standardních operátorů dotazů (C#). Někteří poskytovatelé LINQ, například a LINQ to XML, implementují vlastní standardní operátory dotazů a další rozšiřující metody pro Technologie LINQ to SQL jiné typy kromě IEnumerable<T> .

Lambda – výrazy

V předchozím příkladu si všimněte, že se podmíněný výraz ( ) předává metodě jako argument in-line: Tento vložený výraz se nazývá num % 2 == 0 Where výraz Where(num => num % 2 == 0). lambda. Je to pohodlný způsob psaní kódu, který by jinak byl napsán v těžkopádnější podobě jako anonymní metoda, obecný delegát nebo strom výrazů. V jazyce C# => je operátor lambda, který se čte jako "goes to". Na num levé straně operátoru je vstupní proměnná, která odpovídá ve num výrazu dotazu. Kompilátor může odvodit typ , num protože ví, že numbers je obecný IEnumerable<T> typ. Tělo výrazu lambda je stejné jako výraz v syntaxi dotazu nebo v jakémkoli jiném výrazu nebo příkazu jazyka C#. Může zahrnovat volání metod a další složitou logiku. "Vrácená hodnota" je pouze výsledkem výrazu.

Pokud chcete začít používat LINQ, není začínáme používat výrazy lambda ve velké příponě. Některé dotazy však mohou být vyjádřeny pouze v syntaxi metody a některé z nich vyžadují výrazy lambda. Jakmile se seznámíte s výrazy lambda, zjistíte, že jsou výkonným a flexibilním nástrojem v sadě nástrojů LINQ. Další informace najdete v tématu Výrazy lambda.

Skládání dotazů

V předchozím příkladu kódu si všimněte, že metoda je vyvolána pomocí operátoru OrderBy tečky ve volání Where . Where vytvoří filtrované sekvence a pak na této Orderby sekvenci pracuje seřazením. Vzhledem k tomu, že dotazy vrací , můžete je sestavit v syntaxi metody IEnumerable zřetězováním volání metody. To dělá kompilátor na pozadí při psaní dotazů pomocí syntaxe dotazů. A protože proměnná dotazu neukládá výsledky dotazu, můžete ji upravit nebo použít jako základ pro nový dotaz, a to i po jeho spuštění.