Tuesday, November 22, 2016

IEnumerable vs IQueryable

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

      No comments:

      Post a Comment