Sdílet prostřednictvím


Funkce C# podporující LINQ

Výrazy dotazu

Výrazy dotazů používají deklarativní syntaxi podobnou jazyku SQL nebo XQuery k dotazování na System.Collections.Generic.IEnumerable<T> kolekce. V době kompilace se syntaxe dotazu převede na volání metody na implementaci standardních metod dotazu zprostředkovatele LINQ. Aplikace řídí standardní operátory dotazů, které jsou v oboru, zadáním příslušného oboru názvů pomocí direktivy using . Následující výraz dotazu přebírá pole řetězců, seskupí je podle prvního znaku v řetězci a seskupí skupiny.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Implicitně zadané proměnné (var)

Modifikátor var můžete použít k pokynu kompilátoru, aby odvodil a přiřadil typ, jak je znázorněno zde:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Proměnné deklarované jako var silné typy, stejně jako proměnné, jejichž typ zadáte explicitně. Použití var umožňuje vytvářet anonymní typy, ale pouze pro místní proměnné. Další informace naleznete v tématu Implicitně typované místní proměnné.

Inicializátory objektu a kolekce

Inicializátory objektů a kolekcí umožňují inicializovat objekty bez explicitního volání konstruktoru objektu. Inicializátory se obvykle používají ve výrazech dotazu, když projektují zdrojová data do nového datového typu. Za předpokladu, že třída Customer s veřejnými Name vlastnostmi a Phone vlastnostmi, lze inicializátor objektů použít jako v následujícím kódu:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Pokračujte ve třídě Customer , předpokládejme, že existuje volaný IncomingOrderszdroj dat a že pro každou objednávku s velkými OrderSize, chcete vytvořit nový Customer založený na této objednávce. V tomto zdroji dat lze spustit dotaz LINQ a k vyplnění kolekce použijte inicializaci objektů:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

Zdroj dat může mít více vlastností definovaných než Customer třída, například OrderSize, ale s inicializací objektů jsou data vrácená z dotazu vylinuta do požadovaného datového typu. Zvolíte data, která jsou relevantní pro vaši třídu. V důsledku toho teď máte System.Collections.Generic.IEnumerable<T> naplněné novými Customernovými hledanémi. Předchozí příklad lze také napsat v syntaxi metody LINQ:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

Počínaje jazykem C# 12 můžete k inicializaci kolekce použít výraz kolekce.

Další informace naleznete v tématu:

Anonymní typy

Kompilátor vytvoří anonymní typ. Název typu je k dispozici pouze kompilátoru. Anonymní typy poskytují pohodlný způsob, jak dočasně seskupit sadu vlastností ve výsledku dotazu, aniž byste museli definovat samostatný pojmenovaný typ. Anonymní typy se inicializují pomocí nového výrazu a inicializátoru objektů, jak je znázorněno zde:

select new {name = cust.Name, phone = cust.Phone};

Počínaje jazykem C# 7 můžete pomocí řazených kolekcí členů vytvářet nepojmenované typy.

Metody rozšíření

Rozšiřující metoda je statická metoda , která může být přidružena k typu, takže ji lze volat, jako by se jednalo o metodu instance typu. Tato funkce umožňuje v podstatě "přidat" nové metody do existujících typů, aniž byste je skutečně upravovali. Standardní operátory dotazu jsou sada rozšiřujících metod, které poskytují funkce dotazu LINQ pro libovolný typ, který implementuje IEnumerable<T>.

Lambda – výrazy

Výrazy lambda jsou vložená funkce, která pomocí operátoru => odděluje vstupní parametry od těla funkce a lze je převést v době kompilace na delegáta nebo strom výrazu. V programování LINQ narazíte na výrazy lambda, když provedete přímé volání metod standardní operátory dotazu.

Výrazy jako data

Objekty dotazu jsou kompozovatelné, což znamená, že dotaz můžete vrátit z metody. Objekty, které představují dotazy, neukládají výslednou kolekci, ale kroky k vytvoření výsledků v případě potřeby. Výhodou vrácení objektů dotazu z metod je, že je lze dále skládat nebo upravovat. Proto každá návratová hodnota nebo out parametr metody, která vrací dotaz, musí mít také tento typ. Pokud metoda materializuje dotaz na konkrétní List<T> nebo Array typ, vrátí výsledky dotazu místo samotného dotazu. Proměnná dotazu vrácená metodou se stále může skládat nebo upravovat.

V následujícím příkladu první metoda QueryMethod1 vrátí dotaz jako návratovou hodnotu a druhá metoda QueryMethod2 vrátí dotaz jako out parametr (returnQ v příkladu). V obou případech se jedná o vrácený dotaz, nikoli výsledky dotazu.

IEnumerable<string> QueryMethod1(int[] ints) =>
    from i in ints
    where i > 4
    select i.ToString();

void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
    returnQ =
        from i in ints
        where i < 4
        select i.ToString();

int[] nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var myQuery1 = QueryMethod1(nums);

Dotaz myQuery1 se spustí v následující smyčce foreach.

foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}

Umístěním ukazatele myQuery1 myši zobrazte jeho typ.

Dotaz vrácený QueryMethod1 přímo můžete spustit i bez použití myQuery1.

foreach (var s in QueryMethod1(nums))
{
    Console.WriteLine(s);
}

Umístěte ukazatel myši na volání a QueryMethod1 zobrazte jeho návratový typ.

QueryMethod2 vrátí dotaz jako hodnotu jeho out parametru:

QueryMethod2(nums, out IEnumerable<string> myQuery2);

// Execute the returned query.
foreach (var s in myQuery2)
{
    Console.WriteLine(s);
}

Dotaz můžete upravit pomocí složení dotazu. V tomto případě se předchozí objekt dotazu používá k vytvoření nového objektu dotazu. Tento nový objekt vrátí jiné výsledky než původní objekt dotazu.

myQuery1 =
    from item in myQuery1
    orderby item descending
    select item;

// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
    Console.WriteLine(s);
}