IQueryable,IList,IDictionary,ICollection inherits IEnumerable Interface. All the interfaces of type collection will inherits IEnumerable Interface. Differences Between IEnumerable and IQueryable IEnumerable:-when you are running a query which returns of type IEnumerable.
ICollection<T> is an interface that exposes collection semantics such as Add() , Remove() , and Count . Collection<T> is a concrete implementation of the ICollection<T> interface. IList<T> is essentially an ICollection<T> with random order-based access.
IList doesn't support further filtering. IEnumerable exists in System. Collections Namespace. IEnumerable is a forward only collection, it can't move backward and between the items.
List<T> is just an output format, and while it implements IEnumerable<T> , is not directly related to querying. In other words, when you're using IQueryable<T> , you're defining an expression that gets translated into something else.
All of these interfaces inherit from IEnumerable, which you should make sure you understand. That interface basically lets you use the class in a foreach
statement (in C#).
The MSDN documentation for each of these is decent, so I would start there in rounding out your understanding.
I noticed several issues in @gunny229's answer above which is why I'm writing this post. I've mentioned those issues in comment area of his post as well. To correct that post I would have had to rewrite almost entire post so I thought of creating my own. I don't intend to cater OP's question in entirety but I'm want to point out the difference between IQueryable and IEnumerable when using LINQ to SQL.
I created following structure in DB (DDL script):
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)
Here is the record insertion script (DML script):
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO
Now my goal was to simply get top 2 records from Employee
table in database. So, I added an ADO.NET Entity Data Model item into my console application pointing to Employee
table in my database and started writing LINQ queries.
Code for IQueryable route:
using (var efContext = new EfTestEntities())
{
IQueryable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
When I started to run this program, I had also started a session of SQL Query profiler on my SQL Server instance and here is the summary of execution:
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
It is just that IQueryable
is smart enough to apply the Top (2)
clause on database server side itself so it brings only 2 out of 5 records over the wire. Any further in-memory filtering is not required at all on client computer side.
Code for IEnumerable route:
using (var efContext = new EfTestEntities())
{
IEnumerable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
Summary of execution in this case:
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]
Now the thing is IEnumerable
brought all the 5 records present in Salary
table and then performed an in-memory filtering on the client computer to get top 2 records. So more data (3 additional records in this case) got transferred over the wire unnecessarily.
IQueryable,IList,IDictionary,ICollection inherits IEnumerable Interface. All the interfaces of type collection will inherits IEnumerable Interface.
Differences Between IEnumerable and IQueryable IEnumerable:-when you are running a query which returns of type IEnumerable. IEnumerable will first Executes the first query and then executes the sub queries written for that query.
Example:-If you want get the top 10 population Records from a Particular country then the query we will use in LinQ is
IEnumerable _Population=from s in India select s.population;//First Query _Population=_Population.take(10);//Second Query
Now if we execute this query First Query will be executed first the IEnumerable will get the Records of all the population from the sql server then it will store the data in the In Process memory and then it executes the top 10 population in the next Query.(Execution is taken place for two times on sql server).
if we execute the same query by using IQueryable .
IQueryable _Population=from s in India select s.population;//First Query _Population=_Population.take(10);//Second Query
in this IQueryable it will execute the two Queries at the same time in the sense it will get the population which is of top 10 in a single Query instead of getting the data and filtering the first 10 again.(One time execution on sql server).
Conclusion for IQueryable and IEnumerable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With