Middle
Co je IQueryable v kontextu C#?
sobes.tech AI
Odpověď od AI
IQueryable<T> je rozhraní v LINQ, které umožňuje vytvářet a spouštět dotazy na datových zdrojích podporujících odložené vyhodnocení a konstrukci stromů výrazů.
Klíčové vlastnosti:
- Odložené vyhodnocení: Dotaz se nespouští ihned při jeho sestavení, ale až při potřebě získat výsledky (například při iteraci přes kolekci nebo volání
ToList(),ToArray()). - Strom výrazů: Dotaz je reprezentován jako strom výrazů (
Expression<Func<T>>), který lze analyzovat a převést na něco, co datový zdroj pochopí (například SQL dotaz pro databázi). - Filtrování a projekce na straně datového zdroje: Díky stromu výrazů mohou být operace filtrování (
Where), řazení (OrderBy) a projekce (Select) prováděny na straně datového zdroje, což výrazně zvyšuje výkon, zejména při práci s velkými objemy dat.
Rozdíly od IEnumerable<T>:
| Charakteristika | IEnumerable<T> |
IQueryable<T> |
|---|---|---|
| Vyhodnocení | Okamžité/odložené (závisí na zdroji) | Odložené |
| Získání dat | Celá kolekce může být načtena do paměti | Načítají se pouze potřebná data po spuštění |
| Kde se provádí filtrování/projekce | V paměti aplikace | Na straně datového zdroje |
| Základ | Kolekce v paměti, pole | Datové zdroje (databáze, webové služby apod.) |
| Podpora výrazů | Ne (používá delegáty Func<T>) |
Ano (používá stromové výrazy Expression<Func<T>>) |
Příklad použití:
using System.Linq;
using System.Collections.Generic;
// Předpokládejme, že toto je datový zdroj podporující IQueryable
public class DataSource
{
private List<Person> people = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Charlie", Age = 35 }
};
public IQueryable<Person> GetPeople()
{
// Ve skutečnosti by to byla volání na databázi nebo jiný zdroj
return people.AsQueryable();
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// Použití
public class Program
{
public static void Main(string[] args)
{
DataSource dataSource = new DataSource();
// Vytvoření dotazu s IQueryable - dotaz ještě není spuštěn
IQueryable<Person> query = dataSource.GetPeople()
.Where(p => p.Age > 28)
.OrderBy(p => p.Name);
// Spuštění dotazu při iteraci
foreach (var person in query)
{
Console.WriteLine($"{person.Name}, {person.Age}");
}
// Spuštění dotazu při převodu na seznam
List<Person> seniors = query.ToList();
}
}