I am sure most of you have seen the following interfaces when you write code with .NET Framework.
Have you ever wondered what these really are. Let’s see the beauty of them and let’s have a dig into IEnumerable<T> and IQueryable<T>.
First let’s see how MSDN describes these four interfaces.
Exposes an enumerator, which supports a simple iteration over a non-generic collection.
public interface IEnumerable
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
public interface IEnumerable<out T> : IEnumerable
Provides functionality to evaluate queries against a specific data source wherein the type of the data is not specified.
public interface IQueryable : IEnumerable
{
Type ElementType { get; }
Expression Expression { get; }
IQueryProvider Provider { get; }
}
Provides functionality to evaluate queries against a specific data source wherein the type of the data is known.
public interface IQueryable<out T> : IEnumerable<T>,
IQueryable, IEnumerable
So it seems mainly what is common about all four of these is that they are iterators. Which means we can traverse through the items. If we know the type of the collection that we are going to iterate (a generic type), we can use IEnumerable<T> or IQueryable<T>, and if we don’t know the type (a non-generic type) we can use IEnumerable or IQueryable.
As you can see IQueryable and IQueryable<T> contains three additional properties which are not present in IEnumerable and IEnumerable<T>.
Assuming that we know the type (which means we can use either IEnumerable<T> or IQueryable<T>), let’s compare IEnumerable<T> and IQueryable<T>.
For better understanding let me go with an example here. I have a very simple database which is called “DemoDB” and it contains a single table “Employee”. “Employee” table consists of three columns which are “EmployeeId”, ”FirstName” and “LastName”. I have the following values in it.
sample data
Now I have added an ADO.NET Entity Data Model to my application and selected Generate from database and selected my “DemoDB”. Entity framework will create all the necessary classes to query my database.
I have following two helper methods to query data with the condition Employees with their Last Name “Smith”, one for IEnumerable<T> and the other for IQueryable<T>. I am calling them from my Main method.
static void CallWithIEnumerable(DemoDBEntities oDemoDBEntities)
IEnumerable<Employee> employeeList =
oDemoDBEntities.Employees.Where(e => e.LastName == "Smith");
foreach (Employee employee in employeeList)
Console.WriteLine(employee.FirstName);
static void CallWithIQueryable(DemoDBEntities oDemoDBEntities)
IQueryable<Employee> employeeList =
Now if we examine the SQL queries generated for above two scenarios we are getting the following.
--IEnumerable
SELECT
[Extent1].[EmployeeId] AS [EmployeeId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName]
FROM [dbo].[Employee] AS [Extent1]
WHERE 'Smith' = [Extent1].[LastName]
--IQueryable
They are the same. Now let’s modify our helper methods to get TOP 1 record.
employeeList = employeeList.Take(1);
And if we examine the queries now we are getting the following:
--IEnumerable with top
--IQueryable with top
SELECT TOP (1)
For IEnumerable<T>, it was the same query as the previous, but for the IQueryable<T>, the query has changed amazingly to get TOP 1 directly.
So now we know something additional is happening with IQueryable<T> and let’s find out what.
Now comes the property Expression of IQueryable<T> to the scene. The Expression property gets the expression tree that is associated with the instance. In simple Expression trees represent code in a tree-like data structure (I am not going to go further with Expression trees here, may be it can be a separate post).
So what happens here is, the instruction set will get embedded as a Expression and passed to the compiler. The compiler analyses the instructions (in here it is a SQL Query) and selects the best way to execute it.
Now comes the question when to use IEnumerable<T> or IQueryable<T>.
So that's it. Appreciate your feedback. And please correct me if I am wrong here.
You can find the sample code here. Download Sample
// Type: System.Linq.Enumerable
// Assembly: System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Core.dll
public
static
class
Enumerable
IEnumerable<TSource> Where<TSource>(
this
IEnumerable<TSource> source,
Func<TSource,
bool
> predicate)
return
(IEnumerable<TSource>)
new
Enumerable.WhereEnumerableIterator<TSource>(source, predicate);
// Type: System.Linq.Queryable
Queryable
IQueryable<TSource> Where<TSource>(
IQueryable<TSource> source,
Expression<Func<TSource,
>> predicate)
source.Provider.CreateQuery<TSource>(
Expression.Call(
null
,
((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(
Type[] {
typeof
(TSource) }),
Expression[] { source.Expression, Expression.Quote(predicate) }));
* .NET Framework Libraries Available Source Code Components
* Difference Between IEnumerable and IQueryable
* Enumerable Class - Implement IEnumerable<T> on Mono Open Source Project (check the method where, which return CreateWhereIterator)
* Queryable Class - Implement IQueryable<T> on Mono Open Source Project (check the method where, which return source.Provider.CreateQuery<TSource>)
Balaji M Kundalam edited Revision 7. Comment: Added tags
Maheshkumar S Tiwari edited Revision 3. Comment: Added Tag
Maheshkumar S Tiwari edited Revision 4. Comment: Added Tag
pituach edited Revision 8. Comment: Adding section "References & Resources". I think it is very easy to understand the differences, if we look at the code itself.
pituach edited Revision 9. Comment: adding Appendices A,B & References to Mono Project code
Jaliya Udagedara edited Revision 11. Comment: Removed my signature
Interesting article but I think needs more explanations and more examples.