Reputation: 1031
I'm developing an OData endpoint to return a list of items from a database.
I'm returning an IQueryable
and letting the front end handling the querying / filtering / expanding / paging through the odata query options.
Consider the following method:
[ODataRoute]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IActionResult Get() {
return Ok(context.Vendors.AsQueryable());
}
I understand that async
is not really needed, because the query is not being materialized here.
In this context, when is the query being materialized?
Is it being done in an asynchronous fashion?
Upvotes: 4
Views: 2698
Reputation: 103
UPD: Modified to better address the question than earlier.
In this context, when is the query being materialized?
By using the [EnableQuery]
attribute, you activate the OData action filter, which executes portions of OData logic before and after your Get()
action.
Depending on the response from your action, the query is handled accordingly. For example, query options like $select
and $expand
are applied here. You can refer to ExecuteQuery of EnableQueryAttribute for more details.
ODataSerializerProvider
determines how to serialize the response of the operation.
For collections, the query is materialized using ODataResourceSetSerializer and written to the response output stream.
Is it being done in an asynchronous fashion?
It depends on response type of your action.
To execute the query truly asynchronously, you need to explicitly return either an IAsyncEnumerable<T>
or ActionResult<IAsyncEnumerable<T>>
from the controller.
See a bit more detailed explanation here: https://stackoverflow.com/a/78312071/9862613
Upvotes: -1
Reputation: 20987
You asked a few question Ill try to answer them all and clarify a few questions.
I understand that async is not really needed
Async is never really needed the question is will async benefit your application. E.g When a call is being made to the DbContext there is some network operations which take time, If you do not use async during that time a thread will be waiting for a response, instead of being return to the thread pool to handle other requests.
So yes, it's not needed but it could be useful.
In this context, when is the query being materialized?
The query is materialized (in the middleware) when the endpoint is accessed,
Is it being done in an asynchronous fashion?
No, When you pass the Queryable you are just deferring the execution until later this is still being done synchronously, you need to be using the async/await pattern for you to be doing something asynchronously
Upvotes: 1
Reputation: 1705
Your query will be materialised during serialisation. When your method is accessed, to return the response in JSON, the serialiser tries to serialise the result. At that point, your query actually hits the database and result returned. The application might be slow because of no filters being applied and your query trying to retrieve all the records from the database.
Upvotes: 0