OData / OData/AspNetCoreOData

Executing OData filter server side does not work

Open
#852 11 comments 0 reactions 1 assignee View on GitHub

@lisicase is already working on this.

Since Mar 7, 2023.

feature
Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Description

Assemblies affected
I'm using AutoMapper.AspNetCore.OData.EFCore 4.0.0 with Microsoft.AspNetCore.OData 8.0.6.

Describe the bug
My use case is as follows:
In the frontend application the user can build a complex OData filter which we then save in our database.
An AWS lambda function then needs to query the dataset using this saved filter (for example:
(assigneeId in ('8201014','3038351')) and (user/status eq 'active'))

I've been looking into instantiating ODataQueryOptions like described here, but it doesn't seem to work.

This is what I have right now. The filter is added to the query collection of the request, but somehow they aren't applied to the ODataQueryOptions (filter is still null).

    public async Task<IQueryable<TContract>> GetQueryableFromString<TEntity, TContract>(
        string entitySetName,
        string odataQuery,
        Expression<Func<TEntity, bool>> filter = null,
        QueryStrategy queryStrategy = QueryStrategy.AllFilters)
             where TEntity : class
             where TContract : class
    {
        IEdmModel model = ODataEdmModelProvider.BuildEdmModel();
        IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet(entitySetName);
        if (entitySet is null)
        {
            throw new Exception();
        }

        Type clrType = typeof(TContract);
        List<ODataPathSegment> segments = new() 
        { 
            new EntitySetSegment(entitySet),
        };
        ODataPath path = new(segments);
        ODataQueryContext context = new(model, clrType, path);

        HttpRequest request = new DefaultHttpContext().Request;
        Dictionary<string, StringValues> dictionary = new()
        {
            { "filter", new StringValues(odataQuery) }
        };
        request.Query = new QueryCollection(dictionary);
        ODataQueryOptions<TContract> options = new(context, request);

        DbSet<TEntity> set = _dbSetProvider.DbSetOf<TEntity>();

        IQueryable<TEntity> query = filter is null ? set.AsQueryable() : set.Where(filter);
        
        return await query.GetQueryAsync(_mapper, options, _querySettings);
    }

Reproduce steps
N/A

Data Model
N/A

EDM (CSDL) Model
N/A

Request/Response
N/A

Expected behavior
N/A

Screenshots
N/A

Additional context
N/A

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.