Ответ
IQueryable<T> представляет запрос к источнику данных (например, БД), который может быть дополнительно скомпонован и выполнен с отложенным выполнением. Вот практический пример с Entity Framework Core:
// Метод в репозитории или сервисе, возвращающий IQueryable
public IQueryable<Product> GetProductsQueryable()
{
// _context - это экземпляр вашего DbContext
return _context.Products.AsQueryable();
}
// Использование: построение и выполнение запроса
public List<Product> GetExpensiveProducts(decimal minPrice)
{
// Запрос еще не выполнен, строится выражение
var query = GetProductsQueryable()
.Where(p => p.Price > minPrice)
.OrderByDescending(p => p.Price);
// Выполнение происходит здесь (при вызове ToListAsync, FirstOrDefault и т.д.)
return query.ToList();
}
Ключевые моменты:
- Отложенное выполнение: Запрос выполняется не при возврате
IQueryable, а только при вызове метода материализации (ToList(),FirstOrDefault(),Count()и т.д.). - Композиция: Вы можете последовательно добавлять условия (
Where), сортировку (OrderBy), пагинацию (Skip/Take) к одному базовомуIQueryable. - Преобразование в SQL: В случае с EF Core, все условия, добавленные к
IQueryable, будут преобразованы в единый SQL-запрос и выполнены на стороне базы данных, что эффективно.
Практический пример с фильтрацией на клиенте (не рекомендуется для БД):
// Если источник данных - коллекция в памяти
public IQueryable<Product> GetProductsFromList()
{
List<Product> products = GetProductsFromSomewhere();
return products.AsQueryable(); // Преобразование в IQueryable
}
// Теперь к нему также можно применять методы Linq, но они будут выполняться в памяти (LINQ to Objects).