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