You might have seen IEnumerable, IEnumerable<T> and IQueryable, IQueryable<T> being used in lot of LINQ queries. Today we are going to discuss these items in details.
- IEnumerable - Exposes an enumerator, which supports a simple iteration over a non-generic collection. (what it means in code is iterating a collection using foreach loop)
- Extensively used in .NET non-generic collections.
- IEnumerable<T> - Exposes an enumerator, which supports a simple iteration over a collection of a specified type. "T" represents the type of data to enumerate.
- Derived from IEnumerable interface.
- Extensively used in .NET generic collections.
- Since interfaces can't be extend using extension methods, the static class Enumerable is used for extending it by adding the Extension Methods. Example: Select, Any, Join, Count etc.
- Enumerable - Provides a set of static methods for querying objects that implements System.Collections.Generic.IEnumerable<T>
- IQueryable - Provide functionality to evaluate queries against a specific data source wherein the type of data is not specified.
- Derived from IEnumerable interface.
- Third party data providers must implement IQueryable or IQueryable<T> interface, in order to support LINQ.
- IQuerable<T> - Provide functionality to evaluate queries against a specific data source wherein the type of data is know. "T" represents the type of data in the data source.
- Derived from IEnumerable, IEnumerable<T>, and IQueryable interfaces.
- Since interfaces can't be extended using extension methods, the static class Queryable is used for extending it by adding the Extension Methods. Example: Select, Any, Join, Count etc.
- Queryable - Provides a set of static methods for querying objects that implements System.Linq.IQueryable<T>
Similarity between IEnumerable and IQuerable
- Both can move forward only over a collection, they can’t move backward and between the items.
Difference between IEnumerable and IQuerable
- Namespace - IEnumerable is in System.Collections, where as IQuerable is in System.Linq.
- Derived from - No base interface for IEnumerable where as IQueryable is derived from IEnumerable.
- How does it work - While querying data from database, IEnumerable executes select query on the server, load data in-memory on client side and then filters data, where as IQuerable executes query on server side with all filters. Since IEnumerable does more work, it is slow compare to IQuerable.
- Suitable for - IEneumerable is suitable for LINQ to Object and LINQ to XML queries, where as IQuerable is suitable for LINQ to SQL queries.
- When to use -
- Use IEnumerable while querying data in-memory collections, example:List, Array etc. Use IQuerable data from out-memory (like remote databse or services) collections.
- Use IQuerable when you want to apply filter before the query is being executed.
- Use IQuerable, when lazy loading is needed (you get what you need, not the entire list of records).
- Extension method parameter - IEnumerable uses Func, where as IQuerable uses Expression Tree.
- Custom query - IEnumerable doesn't support where as IQueryable supports using CreateQuery and Execute methods.
- Deferred Execution - Supported in both.
- Lazy loading - IEnemerable doesn't support lazy loading hence it is not suitable for paging like scenarios where as IQuerable supports lazy loading hence suitable for paging like scenarios.
- Best uses - IEnumerable is best used in in-memory traversal. IQueryable is best used in paging like scenarios.
Example: Lets say we have a need to get the first 10 employees from the database and the database contains 1000 employees.
- If we use IEnumerable to get the first 10 employees, we will be end up loading all the 1000 employees and then selecting first 10.
IEnumerable<Employee> employee = dbContext.Employees.Take(10).ToList();
- If we use IQuerable, we get only first 10 emplyees from the query which saves a lot of resource.
IQuerable<Employee> employee = dbContext.Employees.Take(10).ToList();