Site icon TAAGUNG

All About IEnumerable and IQueryable

Download the source code from github and experiment.

Introduction

When we talk about LINQ, we consider two collections IEnumerable and IQueryable. In this article, we will know all about IEnumerable and IQueryable except how they are evaluated. Possibly i will cover that in next article to strengthen our basic understanding.

Code Example

In this example, We are going to fetch the top 1 name, who works with Project “TAAGUNG”. Table structure and data is as follow –

Table structure and Data

For this we will be using same query with different return type as shown below. Certainly they return the same result.

       static void QueryWithIEnumerable(StudyEntities studyEntities)
        {
            IEnumerable<PROJECT_TEAM> projects =
                studyEntities.PROJECT_TEAM.Where(e => e.PRJ_ID.Equals("TAAGUNG"));
            Console.WriteLine(projects.ToString());
            projects = projects.Take(1);
            Console.WriteLine(projects.ToString());
            foreach (var project in projects)
            {
                Console.WriteLine(project.FRST_NM + " " + project.LAST_NM);
            }
        }
        static void QueryWithIQueryable(StudyEntities studyEntities)
        {

            IQueryable<PROJECT_TEAM> projects =
                studyEntities.PROJECT_TEAM.Where(e => e.PRJ_ID.Equals("TAAGUNG"));
            projects = projects.Take(1);
            Console.WriteLine(projects.ToString());

            foreach (var project in projects)
            {
                Console.WriteLine(project.FRST_NM + " " + project.LAST_NM);
            }
        }

How does it work?

For IQueryable, generated query is this. Please note the TOP(1) in the first line.

SELECT TOP (1)
    [Extent1].[PRJ_ID] AS [PRJ_ID],
    [Extent1].[FRST_NM] AS [FRST_NM],
    [Extent1].[LAST_NM] AS [LAST_NM]
    FROM (SELECT
    [PROJECT_TEAM].[PRJ_ID] AS [PRJ_ID],
    [PROJECT_TEAM].[FRST_NM] AS [FRST_NM],
    [PROJECT_TEAM].[LAST_NM] AS [LAST_NM]
    FROM [dbo].[PROJECT_TEAM] AS [PROJECT_TEAM]) AS [Extent1]
    WHERE 'TAAGUNG' = [Extent1].[PRJ_ID]

While IEnumerable generates the following SQL query and then performs in-memory filtering of data. i.e. getting the required data is 2 steps process.

SELECT
    [Extent1].[PRJ_ID] AS [PRJ_ID],
    [Extent1].[FRST_NM] AS [FRST_NM],
    [Extent1].[LAST_NM] AS [LAST_NM]
    FROM (SELECT
    [PROJECT_TEAM].[PRJ_ID] AS [PRJ_ID],
    [PROJECT_TEAM].[FRST_NM] AS [FRST_NM],
    [PROJECT_TEAM].[LAST_NM] AS [LAST_NM]
    FROM [dbo].[PROJECT_TEAM] AS [PROJECT_TEAM]) AS [Extent1]
    WHERE 'TAAGUNG' = [Extent1].[PRJ_ID]

Based on this we can easily depict the processing of these two in the following 2 images.


IQUERYABLE
IEnumerable

Moreover, We can see above, query is written in two statements. If our LINQ is written in one statement like this

IEnumerable<PROJECT_TEAM> projects = studyEntities.PROJECT_TEAM
.Where(e => e.PRJ_ID.Equals("TAAGUNG")).Take(1);

IEnumerable<PROJECT_TEAM> projects = studyEntities.PROJECT_TEAM
.Where(e => e.PRJ_ID.Equals("TAAGUNG")).Take(1);

Then, it will generate this same query in both of the scenario. So Please notice the different way of writing the queries in both of the scenarios. i.e. everything is mentioned in the single query.

SELECT TOP (1)
    [Extent1].[PRJ_ID] AS [PRJ_ID],
    [Extent1].[FRST_NM] AS [FRST_NM],
    [Extent1].[LAST_NM] AS [LAST_NM]
    FROM (SELECT
    [PROJECT_TEAM].[PRJ_ID] AS [PRJ_ID],
    [PROJECT_TEAM].[FRST_NM] AS [FRST_NM],
    [PROJECT_TEAM].[LAST_NM] AS [LAST_NM]
    FROM [dbo].[PROJECT_TEAM] AS [PROJECT_TEAM]) AS [Extent1]
    WHERE 'TAAGUNG' = [Extent1].[PRJ_ID]

Relationship

When we see the definition (F12) of IQueryable, we see it implements IEnumerable

 public interface IQueryable<out T> : IEnumerable<T>, IEnumerable, IQueryable
    {
    }

 public interface IQueryable : IEnumerable
    {
    }

With this, IQueryable gets these 3 additional read only properties

public interface IQueryable : IEnumerable
    {
        //
        // Summary:
        //     Gets the expression tree that is associated with the instance of System.Linq.IQueryable.
        //
        // Returns:
        //     The System.Linq.Expressions.Expression that is associated with this instance
        //     of System.Linq.IQueryable.
        Expression Expression { get; }
        //
        // Summary:
        //     Gets the type of the element(s) that are returned when the expression tree associated
        //     with this instance of System.Linq.IQueryable is executed.
        //
        // Returns:
        //     A System.Type that represents the type of the element(s) that are returned when
        //     the expression tree associated with this object is executed.
        Type ElementType { get; }
        //
        // Summary:
        //     Gets the query provider that is associated with this data source.
        //
        // Returns:
        //     The System.Linq.IQueryProvider that is associated with this data source.
        IQueryProvider Provider { get; }
    }

Similarities

Differences

Feature IEnumerableIQueryable
NamespaceSystem.CollectionSystem.Linq
Lazy LoadingNo SupportSupported
Custom QueryNo SupportSupported

What to use when?

IEnumerable
IQueryable

References

I hope I could clear the basic concepts of these two. Source code is available here to experiment.

Exit mobile version