Sdílet prostřednictvím


Funkce jazyka C#, které podporují LINQ

Výrazy dotazů

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 kompilátor převede syntaxi dotazu na volání metod k implementaci standardních metod dotazu zprostředkovatele LINQ. Aplikace ovládají standardní operátory dotazů, které jsou v rozsahu, 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 každého řetězce a seřadí 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 jsou silně typované, 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 objektů a kolekcí

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 existuje třída Customer s veřejnými vlastnostmi Name a Phone, můžete použít inicializátor objektů, jak je uvedeno v následujícím kódu:

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

Pokračujte ve třídě Customer, předpokládejte, že existuje zdroj dat nazvaný IncomingOrders, a že pro každou objednávku s velkými OrderSize chcete vytvořit nové Customer na základě této objednávky. U tohoto zdroje dat můžete spustit dotaz LINQ a pomocí inicializace objektů vyplnit kolekci:

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 definováno více vlastností než třída Customer, například OrderSize, ale při inicializaci objektu se data vrácená z dotazu přetvoří na požadovaný datový typ; vyberete si data, která jsou relevantní pro vaši třídu. Díky tomu máte nyní System.Collections.Generic.IEnumerable<T> naplněné novými Customery, které jste chtěli. Předchozí příklad můžete 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 najdete tady:

Anonymní typy

Kompilátor vytvoří anonymní typ. K názvu typu má přístup pouze kompilátor. 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 inicializujete 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.

Členové rozšíření

Člen rozšíření je statický člen statické třídy asociované s typem označovaným jako typ příjemce. Člena rozšíření můžete volat tak, jako by byl členem typu příjemce. Tato funkce umožňuje přidávat nové členy 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>.

Výrazy lambda

Výraz lambda je 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 lambda výrazy, když přímo voláte metody na standardních operátorech 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 můžete dále vytvářet nebo upravovat. Proto všechny návratové hodnoty nebo out parametru 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. Stále můžete vytvořit nebo upravit proměnnou dotazu vrácenou metodou.

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);

Následující smyčka foreach provede dotaz myQuery1.

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

Přejeďte ukazatelem myši přes myQuery1, abyste zjistili jeho typ.

Můžete také přímo spustit dotaz vrácený z QueryMethod1, aniž byste použili myQuery1.

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

Umístěte ukazatel myši na QueryMethod1 volání a 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);
}