Sobes.tech
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();
    }
}