Sobes.tech
Middle

Czym jest IQueryable w kontekście C#?

sobes.tech AI

Odpowiedź od AI

IQueryable<T> jest interfejsem w LINQ, który umożliwia tworzenie i wykonywanie zapytań do źródła danych obsługującego opóźnioną ocenę i możliwość tworzenia drzewa wyrażeń.

Kluczowe cechy:

  • Opóźniona ocena: Zapytanie nie jest wykonywane od razu podczas tworzenia, lecz tylko wtedy, gdy konieczne jest uzyskanie wyników (np. podczas iteracji po kolekcji lub wywołania ToList(), ToArray()).
  • Drzewo wyrażeń: Zapytanie jest reprezentowane w formie drzewa wyrażeń (Expression<Func<T>>), które może być analizowane i przekształcane w coś zrozumiałego dla źródła danych (np. zapytanie SQL dla bazy danych).
  • Filtrowanie i projekcja po stronie źródła danych: Dzięki drzewu wyrażeń operacje filtrowania (Where), sortowania (OrderBy) i projekcji (Select) mogą być wykonywane po stronie źródła danych, co znacznie zwiększa wydajność, szczególnie przy pracy z dużymi ilościami danych.

Różnice w stosunku do IEnumerable<T>:

Cecha IEnumerable<T> IQueryable<T>
Ocena Natychmiastowa/odroczona (zależy od źródła) Opóźniona
Pobieranie danych Cała kolekcja może być załadowana do pamięci Ładowane są tylko potrzebne dane po wykonaniu
Gdzie wykonywana jest filtracja/projekcja W pamięci aplikacji Po stronie źródła danych
Podstawa Kolekcje w pamięci, tablice Źródła danych (bazy danych, serwisy internetowe itp.)
Obsługa wyrażeń Nie (używa delegatów Func<T>) Tak (używa drzew wyrażeń Expression<Func<T>>)

Przykład użycia:

using System.Linq;
using System.Collections.Generic;

// Załóżmy, że to jest źródło danych obsługujące 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()
    {
        // W rzeczywistej sytuacji byłoby to zapytanie do bazy danych lub innego źródła
        return people.AsQueryable();
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Użycie
public class Program
{
    public static void Main(string[] args)
    {
        DataSource dataSource = new DataSource();

        // Tworzenie zapytania z IQueryable - zapytanie jeszcze nie jest wykonane
        IQueryable<Person> query = dataSource.GetPeople()
            .Where(p => p.Age > 28)
            .OrderBy(p => p.Name);

        // Wykonanie zapytania podczas iteracji
        foreach (var person in query)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }

        // Wykonanie zapytania podczas konwersji do listy
        List<Person> seniors = query.ToList();
    }
}