Sobes.tech
Middle

Какво е IQueryable в контекста на C#?

sobes.tech AI

Отговор от AI

IQueryable<T> представлява интерфейс в LINQ, който позволява създаването и изпълнението на заявки към източник на данни, поддържащ лениво оценяване и възможност за изграждане на дърво от изрази.

Ключови характеристики:

  • Ленива оценка: Заявката не се изпълнява веднага при създаването ѝ, а само когато е необходимо да се получат резултати (например при итерация през колекция или извикване на ToList(), ToArray()).
  • Дърво от изрази: Заявката е представена като дърво от изрази (Expression<Func<T>>), което може да бъде анализирано и преобразувано в нещо, което източникът на данни разбира (например SQL заявка към база данни).
  • Филтриране и проекция на страната на източника на данни: Благодарение на дървото от изрази, операциите по филтриране (Where), сортиране (OrderBy) и проекция (Select) могат да бъдат изпълнени на страната на източника на данни, което значително повишава производителността, особено при работа с големи обеми данни.

Разлики от IEnumerable<T>:

Характеристика IEnumerable<T> IQueryable<T>
Оценка Немедлена/Отложена (зависи от източника) Ленива
Извличане на данни Цялата колекция може да бъде заредена в паметта Зареждат се само необходимите данни след изпълнение
Къде се изпълнява филтрирането/проекцията В паметта на приложението На страната на източника на данни
Основа Колекции в паметта, масиви Източници на данни (бази данни, уеб услуги и др.)
Поддръжка на изрази Не (използва делегати Func<T>) Да (използва дървета от изрази Expression<Func<T>>)

Пример за използване:

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

// Представяме си, че това е източник на данни, поддържащ 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()
    {
        // В реална ситуация това би било обръщение към база данни или друг източник
        return people.AsQueryable();
    }
}

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

// Използване
public class Program
{
    public static void Main(string[] args)
    {
        DataSource dataSource = new DataSource();

        // Създаване на заявка с IQueryable - заявката все още не е изпълнена
        IQueryable<Person> query = dataSource.GetPeople()
            .Where(p => p.Age > 28)
            .OrderBy(p => p.Name);

        // Изпълнение на заявката при итерация
        foreach (var person in query)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }

        // Изпълнение на заявката при преобразуване в списък
        List<Person> seniors = query.ToList();
    }
}