C# IEnumerable vs IQueryable — Complete Guide
In this tutorial, you'll learn about C# IEnumerable vs IQueryable. We cover key concepts, practical examples, and best practices.
You query a database with LINQ, filter with .Where(), and it returns all rows before filtering. The query ran in memory instead of SQL. You used IEnumerable<T> where IQueryable<T> was needed — or vice versa. Choosing the wrong interface impacts performance and correctness.
Wrong
// IEnumerable — filtering happens in memory
IEnumerable<Order> orders = db.Orders;
var bigOrders = orders.Where(o => o.Total > 1000).ToList();
Output: SQL query is SELECT * FROM Orders — all rows loaded into memory. Filtering happens client-side.
Right
// IQueryable — filtering translates to SQL
IQueryable<Order> orders = db.Orders;
var bigOrders = orders.Where(o => o.Total > 1000).ToList();
Output: SQL query is SELECT * FROM Orders WHERE Total > 1000 — filtering happens in the database. Only matching rows are transferred.
The key difference:
| Aspect | IEnumerable<T> |
IQueryable<T> |
|---|---|---|
| Execution | In-memory (LINQ to Objects) | Deferred, composable (LINQ to SQL) |
| Filtering | Client-side after data load | Server-side as SQL WHERE |
| Performance | Loads all data first | Only loads needed rows |
| Use with | Collections, arrays, in-memory data | EF Core, remote data sources |
Prevention
- Use
IQueryable<T>for database queries to ensure server-side evaluation. - Use
IEnumerable<T>for in-memory collections (arrays, lists). - Be aware that calling
ToList(),ToArray(), orAsEnumerable()breaks theIQueryablechain. - Use
AsQueryable()only when you need query composition on in-memory data. - Check the generated SQL (with EF Core logging) to verify server-side evaluation.
- Return
IQueryable<T>from repository methods to allow query composition.
Common Mistakes with ienumerable vs iqueryable
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists - Forgetting
deriving (Show, Eq)on custom data types needed for debugging
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
This pattern is critical in DodaTech's data layer — IQueryable ensures efficient database queries across all products. For more EF Core tips, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro