GAP·MAP
← all breakdowns
C#LINQQuery ProvidersDeferred Executionmiddle level

IEnumerable vs IQueryable: where the query runs

the question

What is the difference between `IEnumerable<T>` and `IQueryable<T>` in C#, and when would you use each one?

what they're testing: The interviewer is probing whether you can predict how LINQ is represented and executed, especially when a query crosses from application code to a remote provider.

a strong answer

IEnumerable<T> is a sequence you can iterate. When its compile-time type selects Enumerable operators, predicates are delegates such as Func<T, bool>. That filtering runs as .NET code during enumeration. The source can be a list, an iterator, or a remote-backed sequence, so IEnumerable<T> does not mean "already in memory."

IQueryable<T> also implements IEnumerable<T>. Its Queryable operators represent calls in an expression tree that a provider can inspect and translate, for example into SQL. Supported Where, OrderBy, and Take calls can therefore run in the database before rows are returned. Translation depends on the provider. Unsupported expressions may throw or require an explicit switch to client-side evaluation.

Both often use deferred execution. Building a query does not necessarily fetch results. Enumeration and operations such as ToList, Count, or First trigger work, and ToList stores the results. Re-enumerating a deferred query can run it again. Keep a database query as IQueryable<T> while composing translatable filters and projections, then materialize at the data-layer boundary. Use IEnumerable<T> when the remaining work should run in .NET or when callers should not compose provider-backed queries.

Where people slip

the tempting wrong answer, and what's actually true

  • `IEnumerable<T>` always means the entire collection is already in memory.

    `IEnumerable<T>` promises iteration, not storage or eager materialization, and its source can produce items lazily.

  • `IQueryable<T>` always runs the query in a database.

    An `IQueryable<T>` delegates execution to its provider, which may translate to SQL, target another source, or execute locally.

  • Calling `ToList()` keeps the query deferred because LINQ is lazy.

    `ToList()` enumerates the query immediately and stores the results in a list.

  • Assigning an `IQueryable<T>` to an `IEnumerable<T>` variable immediately sends the query to the server.

    The assignment does not execute the query. Later standard LINQ calls through the `IEnumerable<T>` variable bind to `Enumerable` operators, but enumerating the source still executes the underlying query.

If they push further

What is the difference between `AsEnumerable()` and `ToList()`?

`AsEnumerable()` exposes the source as `IEnumerable<T>` without executing or copying it, so subsequent standard operators use LINQ to Objects. `ToList()` enumerates immediately and stores the results in a list.

What happens when an Entity Framework Core provider cannot translate part of a query?

EF Core permits client evaluation in the top-level projection, but an untranslatable expression elsewhere causes a runtime exception. Switch explicitly with `AsEnumerable()` only when the data volume and client-side cost are acceptable.

Can enumerating the same query twice execute it twice?

Yes. A deferred query can run on each enumeration, so materialize it once when the same snapshot will be reused.

Sources

Now answer it yourself.

Reading a strong answer is easy. Producing one under pressure is the skill the interview tests. Gapmap grades your answer against the same bar an interviewer would.

was this useful?

beta

The interviewer part is in the works.

The diagnostic, personal maps, and AI mock interviews are being finished right now. The notes stay free either way. Leave an email and you'll get the first-cohort invite, plus a month of Pro when it opens.