Sobes.tech
Middle
126
questionbank

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

Answer from AI

sobes.tech 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()
    {
        // В реальной ситуации đây было бы обращение к базе данных или другому источнику
        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();
    }
}