-
I have a calculated property on each of the rows returned in my query enabled GET method that is very expensive to calculate so am keen on just doing that for just the rows that are in scope as per the incoming top, skip, and count parameters. I'm not doing any filtering of the Ok(IQuerably<DbSet> I'm returning so I presume something in the OData pipeline is filtering these results after my GET method returns? I imagine I can trace through odata code base and find a spot where I might be able to initialise the extra properties of just those records in scope, but am wondering if there's a best practice approach to do this? Maybe overriding an event where can do my scoped calculation or possibly injecting some custom implementation of an interface? Appreciate any thoughts on this! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Figured it out using this post as a starting point For my scenario, simply applying the query options worked best as per below. Note that EntityToModel is a custom conversion function that returns a TModel from a TEntity. It was annoying the ApplyTo wouldn't work with my TEntity class which differed from the public TModel so I used a dictionary map as a bridge to overcome that issue. Hope this helps someone else :) [HttpGet("/odata/[controller]")]
public IActionResult Get(ODataQueryOptions<TModel> options, bool editMode)
{
// validate options
options.Validate(new ODataValidationSettings());
// build entity map
var entityMap = Entities.Where(e => editMode || !e.IsDeleted && e.Status != EntityStatus.New.ToString())
.ToDictionary(e => e.Id, e => e);
// determine results (models need to be fully hydrated to support query options)
var results = new List<TModel>();
var models = entityMap.Values.Select(EntityToModel).ToArray();
foreach (var model in options.ApplyTo(models.AsQueryable()).Cast<TModel>())
{
if (editMode)
{
// update my expensive properties using entityMap to access
// the scoped entities using the Id property of my TModel
}
results.Add(model);
}
// return results
return Ok(results);
} |
Beta Was this translation helpful? Give feedback.
Figured it out using this post as a starting point
For my scenario, simply applying the query options worked best as per below. Note that EntityToModel is a custom conversion function that returns a TModel from a TEntity.
It was annoying the ApplyTo wouldn't work with my TEntity class which differed from the public TModel so I used a dictionary map as a bridge to overcome that issue.
Hope this helps someone else :)