LINQ (Language Integrated Query) je technologie integrovaná v .NET, která umožňuje dotazovat se na data přímo v kódu, ať už se jedná o kolekce v paměti, databáze, XML dokumenty nebo jiné datové zdroje. Jejím hlavním cílem je sjednotit způsob práce s daty bez ohledu na jejich zdroj, aby nebylo nutné učit se specifické dotazovací jazyky pro různé typy úložišť. Díky LINQ lze data filtrovat, řadit, transformovat nebo seskupovat jednoduchým, čitelným a typově bezpečným způsobem.
Vyhodnocování LINQ
LINQ operace mohou být vyhodnocovány dvěma způsoby:
Okamžité vyhodnocení (Immediate Execution)
Výsledek dotazu se vyhodnotí a uloží ihned, například při použití metod jako ToList(), ToArray() nebo Count(). Data se ihned načtou a zpracují.
Odložené vyhodnocení (Deferred Execution)
Dotaz se neprovádí okamžitě, ale až při potřebě získat výsledek (např. v foreach). To umožňuje kombinovat více dotazů bez mezivýsledků a provést vše najednou. Odložené vyhodnocení šetří paměť a umožňuje efektivnější práci s daty, ale může vést ke změnám výsledků, pokud se zdrojová data před vyhodnocením změní.
Lambda funkce (Anonymní funkce)
Lambda funkce je krátká anonymní funkce (anonymní = není pojmenovaná), která může mít parametry a tělo.
Je to zkrácený zápis delegátů (funkcí nebo metod předaných jako parametr).
Typicky se používá ve spojení s LINQ nebo u událostí, callbacků či filtrů.
Syntaxe: (parametry) => výraz
Př.: Jednoduchý příklad: x => x * x
Př.: Příklad s blokem příkazů: (x, y) => { return x + y; }
Ukázky
Filtrace kolekce:
var adults = people.Where(p => p.Age >= 18);
Sečtení dvou čísel:
Func<int, int, int> add = (a, b) => a + b;int result = add(5, 7); // result = 12
LINQ poskytuje mnoho standardních metod, které se nazývají operátory dotazů. Mezi nejpoužívanější patří:
Where – filtruje prvky podle podmínky
var adults = people.Where(p => p.Age >= 18);
Select – transformuje prvky do jiné podoby
var names = people.Select(p => p.Name);
OrderBy / OrderByDescending – řadí prvky
var ordered = people.OrderBy(p => p.Name);
GroupBy – seskupuje prvky podle klíče
var groups = people.GroupBy(p => p.City);
First / FirstOrDefault – získá první prvek (nebo výchozí hodnotu)
var firstAdult = people.FirstOrDefault(p => p.Age >= 18);
Any / All – ověřuje, zda některé nebo všechny prvky splňují podmínku
bool anyMinors = people.Any(p => p.Age < 18);
Count – spočítá prvky
int countAdults = people.Count(p => p.Age >= 18);
Fluent API
V C# se LINQ nejčastěji zapisuje pomocí tzv. Fluent API, kde se jednotlivé metody řetězí za sebe. Tato forma zápisu je přehledná, dobře čitelná a umožňuje snadno vytvářet složité dotazy. FluentAPI není specifické pouze pro jazyk C#, ale lze jej nalézt v mnoha moderních programovacích jazycích
Příklad
Dotaz na všechny osoby starší 18 let seřazené podle jména vzestupně:
var result = people .Where(p => p.Age >= 18) .OrderBy(p => p.Name) .Select(p => new { p.Name, p.Age });
Alternativou Fluent API je dotazovací syntaxe (query syntax), která připomíná SQL:
var result = from p in people where p.Age >= 18 orderby p.Name select new { p.Name, p.Age };
Anonymní objekty
Stejně jako existují anonymní funkce, tak C# podporuje i tvorbu anonymních objektů. Tvoří se tak, že se neuvede datový typ
var person = new{ Name = "Pepa", Age = 38};
Použití anonymních objektů je vhodné jen pokud se jedná o dočasné objekty. Jejich využitím ztrácíme typovou kontrolu a vlastnosti jako například zapouzdření, které nabízí silně typované třídy.