Коли ви працюєте з колекціями в .NET, часто зустрічаєте два важливі інтерфейси: IEnumerable та IQueryable. Хоча обидва можуть використовуватися для ітерації даних, вони суттєво відрізняються в тому, як обробляють запити, отримання даних і виконання. Давайте розглянемо кожен інтерфейс і виокремимо їх ключові відмінності.
Що таке IEnumerable?
IEnumerable — це простий інтерфейс, який дозволяє ітерувати через колекцію елементів. Ви можете уявити його як «список речей», через які ви хочете пройти (наприклад, за допомогою циклу foreach
).
- Простір імен:
System.Collections
абоSystem.Collections.Generic
(дляIEnumerable
). - Використання:
- Зазвичай використовується для обходу колекцій, що зберігаються в пам'яті, таких як Lists або Arrays.
- Підтримує відкладене виконання в LINQ — це означає, що запит виконується, коли ви фактично починаєте ітерацію (наприклад, у циклі
foreach
), а не коли ви його визначаєте. - Ідеально підходить для ситуацій, коли дані вже завантажено в пам'ять.
Приклад
List numbers = new List { 1, 2, 3, 4, 5 };
// numbers є IEnumerable
IEnumerable query = numbers.Where(n => n > 2);
// Справжнє фільтрування ("Where(n => n > 2)") відбувається, коли ви ітеруєте
foreach (var num in query)
{
Console.WriteLine(num);
}
Що таке IQueryable?
IQueryable розширює IEnumerable, але призначений для запитів даних поза пам'яттю — часто використовується для запитів до джерел даних, таких як бази даних. Коли ви пишете LINQ-запит, використовуючи IQueryable, вираз перетворюється в формат, специфічний для джерела даних (наприклад, SQL для реляційної бази даних).
- Простір імен:
System.Linq
. - Використання:
- Зазвичай використовується з Entity Framework або іншими інструментами ORM для запитів до баз даних.
- Перетворює LINQ-запити в команди, специфічні для сховища даних (наприклад, SQL).
- Дозволяє ефективніше фільтрувати на рівні бази даних (наприклад, через умови
WHERE
), замість того, щоб фільтрувати все в пам'яті.
Приклад
// Припустимо, у вас є контекст бази даних 'dbContext'
// та таблиця (сущність) 'Products'
// products є IQueryable
IQueryable products = dbContext.Products
.Where(p => p.Price > 20);
// Вираз вище не виконується негайно.
// Він буде перетворений у SQL, коли дані фактично будуть доступні (через foreach, ToList тощо).
List filteredProducts = products.ToList(); // Справжнє виконання запиту відбудеться тут
Ключові відмінності
- Місце виконання
- IEnumerable працює з даними, що вже знаходяться в пам'яті.
- IQueryable може перетворювати та виконувати запити до зовнішнього джерела даних (наприклад, бази даних), зменшуючи обсяг даних, що завантажуються в пам'ять.
2. Виконання запиту
- IEnumerable зазвичай обробляє фільтри в пам'яті після того, як дані були завантажені.
- IQueryable може передавати фільтри та трансформації до джерела даних, що може призвести до покращення продуктивності, оскільки вибираються лише необхідні дані.
3. Сценарії використання
- IEnumerable чудово підходить для колекцій в пам'яті, простих ітерацій або коли дані не є надто великими.
- IQueryable ідеально підходить, коли потрібно працювати з віддаленими джерелами даних, особливо великими наборами даних у базах даних.
4. Продуктивність
- IEnumerable може бути повільним при роботі з великими наборами даних, оскільки може завантажити все в пам'ять перед застосуванням фільтрів.
- IQueryable може бути більш ефективним для великих наборів даних, оскільки джерело даних виконує основну роботу (наприклад, фільтрацію на рівні бази даних).
Коли використовувати який інтерфейс?
- Використовуйте IEnumerable, якщо ви вже маєте повні дані в пам'яті (наприклад, список або масив) або працюєте з відносно невеликими наборами даних.
- Використовуйте IQueryable, коли потрібно запитувати великі обсяги даних або виконувати складні запити до віддаленого джерела даних. Такий підхід дозволяє отримувати лише відповідні дані, покращуючи продуктивність і використання ресурсів.
Підсумки
І IEnumerable, і IQueryable є основними інтерфейсами в .NET для ітерації через колекції, але вони слугують різним цілям.
IEnumerable найкраще підходить для даних, що зберігаються в пам'яті, тоді як IQueryable проявляє свою силу при запитах до зовнішніх джерел даних — особливо великих. Розуміння того, як працює кожен з них, допоможе вам писати більш ефективний, зручний для обслуговування та продуктивний код.
Перекладено з: IQueryable vs. IEnumerable: Understanding the Basics