Staňte se programátorem: Kouzelný LINQ

Jednou z novinek .NET Frameworku 3.5 byl i velmi diskutovaný LINQ. Ten do rodiny .NET jazyků přináší syntaxi jazyka SQL a také jeho funkčnost pro výběr a řazení dat.

Třetí generace Microsoft .NET Framework obsahuje techniku, která vývojářům dovoluje provádět operace nad daty v paměti mnohem jednodušším a efektivnějším způsobem a to pomocí dotazů podobných jazyku SQL. Jedná se o technologii LINQ (Language INtegrated Query). LINQ dovoluje dotazování, přidávání, filtrování, mazání a editaci dat v polích, kolekcích odvozených od generického rozhraní IEnumerable<T>, XML či SQL databázích. Dohromady tato technologie nabízí čtyři hlavní implementace:

  • LINQ to Objects – Manipulace s daty v paměti
  • LINQ to SQL –Manipulace s daty v databázích hostovaných na MS SQL server
  • LINQ to DataSet – Manipulace s daty uloženými v ADO .NET datasetech
  • LINQ to XML –Manipulace s daty v XML formátu

LINQ to Objects

V tomto článku se budeme zabývat pouze odnoží LINQ to Objects, která je nejjednodušší. Jak jsem již zmínil v úvodu, tato techologie  umožňuje manipulaci s kolekcemi a poli pomocí nových syntaktických výrazů velmi jednoduchým způsobem podobným jazyku SQL. Díky tomu odpadává nutnost vytváření vlastních algoritmů pro vyhledávání a úpravy v kolekcích. Přehled klíčových slov uvádím níže:

  • Select – výběr hodnoty kterou chceme použít
  • SelectMany – výběr více hodnot najednou (např. pole)
  • Join – spojení více poskytovatelů dat
  • GroupBy – rozdělení dat do více skupin podle určitého klíče
  • Where – omezení výběru prvků podle specifikované podmínky
  • OrderBy, OrderByDescending – specifikace třídění, umožňuje výběr elementu podle kterého se má třídit
  • First, Last – výběr prvního nebo posledního prvku z kolekce
  • ElementAt – výběr prvku podle udaného indexu
  • Count – počet prvků v kolekci
  • Union, Intersect, Except – definice množinových operací sjednocení, rozdíl a průnik
  • Sum, Min, Max, Average – vrací součet, minimální, maximální či průměrnou hodnotu z dané kolekce
  • Reverse – otočí pořadí prvků v kolekci
  • Concat – spojí dvě kolekce dohromady
  • OfType – výběr pouze těch prvků, které jsou specifikovaného typu

Obecná forma jednoduchého LINQ dotazu v C# 3.0 tedy vypadá podobně jako v tomto příkladu:

from [typ] proměnná in datový_zdroj
[where] podmínka_restrikce
[orderby] klíč_řazení [descending]
select výraz_projekce

Jak je vidět, datový typ prvku nemusí být ve from klauzuli dotazu explicitně určen a je, stejně jako v případě klíčového slova var, odvozen v době kompilace. Ovšem ne vždy může být datový typ prvku v sekvenci takto odvozen. V případě generické kolekce to možné je, ovšem v případě negenerické kolekce jako je například ArrayList, musí být kolekce buď pomocí Cast metody převedena na kolekci generickou, nebo v případě C# 3.0 query keywords stačí v klauzuli from typ prvku explicitně uvést. Ovšem v případě nesprávně definice typu prvku hrozí opět výjimka InvalidCastException.

A teď už skutečné použití LINQ v praxi. Následující kód  tedy z ArrayListu vybere ty položky, jejichž hodnota je menší než 4 a výsledek seřadí.

ArrayList numbers = new ArrayList() { 1, 2, 3, 4, 5 };
var result = from int n in numbers
                              where n < 4
                              orderby n descending
                              select n;

Použití základních klíčových slov from, select a orderby bylo již demonstrováno v předchozích příkladech, ovšem na použití nových klíčových slov group, join a let se podíváme v následujících příkladech.

Lambda výrazy

LINQ je možné používat v méně upovídané formě také pomocí rozšiřujících metod a lambda výrazů, které slouží ke zkrácení dotazu. Například pokud chceme vybrat všechna slova kratší než 5 znaků z kolekce, použili bychom pravděpodobně tento kód:

string[] slova= {"Ahoj", "Čau", "Dobrý den", "Na shledanou", "Dobrou noc"};

var kratkaSlova = from c in slova
                                          where c.Length < 5
                                          select c
                                          orderby c.Length;

foreach (string slovo in kratkaSlova)
{
     Console.Writeline(slovo);
}

Pomocí lambda výrazů tento dotaz můžeme ještě více zjednodušit:

string[] slova= {"Ahoj", "Čau", "Dobrý den", "Nashledanou", "Dobrou noc"};

var kratkaSlova = slova.Where(c => c.Length < 5).OrderBy(c => c.Length);
foreach (string slovo in kratkaSlova)
{
     Console.Writeline(slovo);
}

Tento kód udělá přesně to samé, co předchozí program, ale využije rozšiřujících metod. V tomto případě umožňuje zavolat metody Where a OrderBy na poli řetězců, protože jsou tyto metody definovány pro všechny objekty implementující rozhraní IEnumerable<T>, které je alespoň co se týče LINQu klíčové.

Úsek kódu Where(c => c.Length < 5) využívá zmíněných lambda výrazů, za c se postupně dosadí každý jednotlivý řetězec z pole slova a vyhodnotí se zadaná podmínka.

Výhodou LINQu je že naprosto stejnou konstrukcí se pracuje s jakýmikoliv daty, takže není problém vyhledávat data v XML souborech či databázích prakticky stejným způsobem.

Klíčové slovo let

Díky tomuto klíčovému slovu lze v LINQ dotazu definovat proměnnou s oborem platnosti pouze v rámci daného dotazu (range variable) a do ní uložit kupříkladu výsledek nějakého pomocného transformačního dotazu nebo obyčejnou pomocnou hodnotu. V následujícím příkladu je klíčového slova let použito k uchování výsledku pomocného dotazu, který převede každý řetězec v kolekci na pole znaků. Současně příklad ukazuje možné použití více než jedné from klauzule v jednom dotazu.

List<string> strings = new List<string>() { "Hello", "Ahoj" };
var result = from s in strings
             let chars = s.ToCharArray()
             from ch in chars
             
where Char.IsUpper(ch)
                              select ch;

//vypise "H" a "A"
foreach (char ch in result)
{
     Console.WriteLine(ch);
}

LINQ je součástí .NET Frameworku verze 3.5. Díky implementaci synatxe podobné SQL usnadňuje práci s výběrem dat přičemž je v rámci LINQ příkazu rovnou i seřadí. Více infromací o LINQ najdete na těchto webech:


Mareš, Amadeo: 1001 tipů a triků pro C#

c_kniha_mares.pngNestačí vám náš seriál? Pořiďte si knihu jeho autora, ve které vás seznámí s tisícovkou programovacích tipů a technik. Díky velkému počtu tipů, návodů, triků a rad kniha poslouží při každé příležitosti. Kdykoli si nevíte rady, stačí nalistovat příslušnou stranu a problém okamžitě vyřešit. Tipy a triky míří především na začínající programátory; užitečné rady tu ovšem najdou i pokročilejší vývojáři a ostřílení znalci. SOučástí publikace je i přiložené DVD, na kterém najdete bezplatné vývojové prostředí Visual C#, databázový server a především všechny zdrojové kódy z knihy, takže je budete moci okamžitě použít.Webové stránky knihy.

Diskuze (79) Další článek: Nová kniha: Flash CS4 - 100 nejlepších postupů

Témata článku: , , , , , , , , , , , , , , , , ,