C#  

IEnumrable and IQueryable in c#

Introduction

If you are learning C#, LINQ, or Entity Framework Core, you will often see two interfaces:

  • IEnumerable<T>

  • IQueryable<T>

Both are used with LINQ, but they work differently.

The main difference is where the query runs.

What is IEnumerable in C#?

IEnumerable<T> is mainly used when the data is already available in memory.

For example :

List<int> numbers = new()
{
    10, 20, 30, 40, 50
};

IEnumerable<int> result = numbers
    .Where(x => x > 20);

Here, the numbers are already in memory, so the Where() condition runs inside the application.

Simple flow :

Data → Memory → LINQ → Result

IEnumerable is commonly used with:

  • List<T>

  • Arrays

  • Collections

  • In-memory data

What is IQueryable in C#?

IQueryable<T> is mainly used for querying external data sources, especially databases.

For example, with Entity Framework Core:

IQueryable<Product> products = dbContext.Products;

var result = await products
    .Where(x => x.Price > 1000)
    .ToListAsync();

Entity Framework Core can convert this LINQ query into SQL.

It may generate SQL similar to:

SELECT * FROM Products WHERE Price > 1000;

The filtering happens in the database instead of loading all products into memory.

Simple flow :

LINQ Query → SQL → Database → Result

IEnumerable vs IQueryable

FeatureIEnumerableIQueryable
Works mainly withIn-memory dataDatabase data
Query runsIn applicationUsually at database
SQL translationNoYes, through provider
Best forSmall/in-memory collectionsDatabase queries
Common withList, ArrayEntity Framework Core

A Database Example

Suppose we have a Products table containing 1 million records.

We want products where:

Price > 1000


Using IQueryable

With Entity Framework Core:

IQueryable<Product> products = dbContext.Products;

var result = await products
    .Where(x => x.Price > 1000)
    .ToListAsync()

Conceptually, the process is:

Application
    ↓
LINQ Where(x => x.Price > 1000)
    ↓
Entity Framework Core
    ↓
SQL
    ↓
Database
    ↓
Only matching records
    ↓
Application

The filtering is performed by the database.

What Happens When You Switch to IEnumerable?

IQueryable<Product> products = dbContext.Products;

IEnumerable<Product> result = products
    .AsEnumerable()
    .Where(x => x.Price > 1000);

AsEnumerable() changes the LINQ operations that follow it to LINQ-to-Objects.

So the Where() after AsEnumerable() is evaluated in the application.

Conceptually:

Database
    ↓
Records are read
    ↓
Application memory
    ↓
Where(x => x.Price > 1000)
    ↓
Filtered result

This can be slow if the database has a lot of records.

If the database contains a large number of records, this can result in unnecessary data transfer and increased memory usage.

Conclusion

IEnumerable<T> is mainly used for working with data in application memory, while IQueryable<T> is used to build queries that can be executed by external data sources such as databases. Understanding where the query is executed helps you write more efficient and performant LINQ and Entity Framework Core code.

Hope this helps you!