Kevin Krumwiede
Kevin Krumwiede

Reputation: 10288

In ASP.NET Core 6, is an IQueryable returned by a controller action enumerated asynchronously?

My question is similar to Making a Web API controller returning a IQueryable list asynchronous from 2013, and related to Should I call ToListAsync() when make a query. I want to focus specifically on the claim by multiple users (including the highly regarded Stephen Cleary) that it is "not necessary" to explicitly enumerate an IQueryable asynchronously.

I know that in recent versions of ASP.NET Core, a controller can return an IAsyncEnumerable and it will be enumerated asynchronously. Is the answer simply that the framework does the same thing with IQueryable?

And to throw a wrench into what may otherwise be a simple answer, do the potential problems with unbuffered streaming of an IAsyncEnumerable also apply to IQueryable?

Upvotes: 1

Views: 906

Answers (1)

Kevin Krumwiede
Kevin Krumwiede

Reputation: 10288

IQueryable doesn't extend IAsyncEnumerable, but the runtime type of an IQueryable may be an IAsyncEnumerable. This is implied by the implementation of AsAsyncEnumerable.

ASP.NET Core does not treat IAsyncEnumerable or IQueryable specially. It defers to System.Text.Json to serialize an object based on its runtime type. We can see how that works by searching the source.

And System.Text.Json does not treat IQueryable specially. If it happens to be an IAsyncEnumerable, it will be treated as such. Otherwise, it will be enumerated synchronously as an IEnumerable. So if you want this default behavior, a controller action can simply return an IQueryable (or Task<IQueryable>, etc.)

The only reason to modify the return type is if you know the IQueryable is an IAsyncEnumerable, and you want to avoid the potential complications of streaming. In that case, call ToListAsync to materialize the result in the controller.

Upvotes: 1

Related Questions