Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How convert result from ApplyTo to IQueryable<T> #865

Closed
petrkasnal opened this issue Mar 21, 2023 · 2 comments
Closed

How convert result from ApplyTo to IQueryable<T> #865

petrkasnal opened this issue Mar 21, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@petrkasnal
Copy link

I am using OData and I don't want to use IQueryable on my controller action. Instead, I am sending ODataQueryOptions to my handler, and ApplyTo is working perfectly, returning an IQueryable. However, now I need an IQueryable and I am stuck. When I don't use $select and $expand, everything is okay.
But when I do use them, I realize that it's not an IQueryable with customers, but with some wrapper called SelectSome. Is there any way to solve this? I tried using SelectExpand, but that didn't help either.

Thank you.

Handler

IQueryable<Customer> customers = _customerRepository.GetAll();

  request.Input.Validate(new ODataValidationSettings()
  {
      AllowedFunctions = AllowedFunctions.AllMathFunctions
  });

  IQueryable data = request.Input.ApplyTo(customers, new ODataQuerySettings()); 

  IQueryable<Customer> dataRdy = data as IQueryable<Customer>; // Not working return null
  IQueryable<Customer> dataRdy2 = data.Cast<Customer>();
  List<Customer> dataList = dataRdy2.ToList(); // Throws an exception below
System.InvalidOperationException: No coercion operator is defined between types 'Microsoft.AspNetCore.OData.Query.Wrapper.SelectSome`1[Domain.Entities.Customer]' and 'Domain.Entities.Customer'.
   at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateCast(ShapedQueryExpression source, Type resultType)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Application.Handlers.TestQueryHandler.Handle(TestQuery request, CancellationToken cancellationToken) in C:\user\workspace\WebApiOpenData\Src\Application\Handlers\TestQuery.cs:line 51
   at Mediator.Behaviors.AuthorizationBehaviour`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
   at WebApi.Controllers.v1.CustomersController.Get(ODataQueryOptions filter) in C:\user\workspace\WebApiOpenData\Src\WebApi\Controllers\v1\CustomersController.cs:line 36
   at lambda_method7(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
@petrkasnal petrkasnal added the bug Something isn't working label Mar 21, 2023
@xuzhg
Copy link
Member

xuzhg commented Mar 21, 2023

@petrkasnal It's same as issue at: #766

You can see some codes about how to process the returns by yourself at: https://github.com/xuzhg/WebApiSample/blob/main/v8.x/CustomizeSelectExpand/CustomizeSelectExpand/Controllers/WeatherForecastController.cs#L69-L85

Meanwhile, I have a PR in the review to add an extension to support this. See here: #824

Do you mind to share your comments so I can improve my design.

@petrkasnal
Copy link
Author

Ok thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants