AspNetCoreOData
AspNetCoreOData copied to clipboard
EF6 Compatibility - $filter ; $select does not work
I used the sample "ODataRoutingSample" and replaced EF-Core with EF6.
It generally works until you use "Queryable Features" like $filter or $select then you will recive this expcetion:
NotSupportedException: Unable to create a constant value of type 'Microsoft.OData.Edm.IEdmModel'. Only primitive types or enumeration types are supported in this context. System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+TypedTranslator<T_Linq>.Translate(ExpressionConverter parent, Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+TypedTranslator<T_Linq>.Translate(ExpressionConverter parent, Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, out DbExpressionBinding binding) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator+OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, out DbExpression source, out DbExpressionBinding sourceBinding, out DbExpression lambda) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator+SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator+SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+TypedTranslator<T_Linq>.Translate(ExpressionConverter parent, Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateSet(Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator+UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator+SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter+TypedTranslator<T_Linq>.Translate(ExpressionConverter parent, Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable<MergeOption> forMergeOption) System.Data.Entity.Core.Objects.ObjectQuery<T>+<>c__DisplayClass41_0.<GetResults>b__1() System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction<T>(Func<T> func, IDbExecutionStrategy executionStrategy, bool startLocalTransaction, bool releaseConnectionOnSuccess) System.Data.Entity.Core.Objects.ObjectQuery<T>+<>c__DisplayClass41_0.<GetResults>b__0() System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute<TResult>(Func<TResult> operation) System.Data.Entity.Core.Objects.ObjectQuery<T>.GetResults(Nullable<MergeOption> forMergeOption) System.Data.Entity.Core.Objects.ObjectQuery<T>.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__31_0() System.Data.Entity.Internal.LazyEnumerator<T>.MoveNext() System.Collections.Generic.List<T>..ctor(IEnumerable<T> collection) Microsoft.AspNetCore.OData.Query.Container.TruncatedCollection<T>..ctor(IQueryable<T> source, int pageSize, bool parameterize) in TruncatedCollectionOfT.cs : base(Take(source, pageSize, parameterize)) Microsoft.AspNetCore.OData.Query.ODataQueryOptions.LimitResults<T>(IQueryable<T> queryable, int limit, bool parameterize, out bool resultsLimited) in ODataQueryOption.cs TruncatedCollection<T> truncatedCollection = new TruncatedCollection<T>(queryable, limit, parameterize);
Show raw exception details TargetInvocationException: Exception has been thrown by the target of an invocation. System.RuntimeMethodHandle.InvokeMethod(object target, object[] arguments, Signature sig, bool constructor, bool wrapExceptions) System.Reflection.RuntimeMethodInfo.Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) System.Reflection.MethodBase.Invoke(object obj, object[] parameters) Microsoft.AspNetCore.OData.Query.ODataQueryOptions.LimitResults(IQueryable queryable, int limit, bool parameterize, out bool resultsLimited) in ODataQueryOption.cs + IQueryable results = genericMethod.Invoke(null, args) as IQueryable; Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplyPaging(IQueryable result, ODataQuerySettings querySettings) in ODataQueryOption.cs + result = LimitResults(result, pageSize, querySettings.EnableConstantParameterization, out resultsLimited); Microsoft.AspNetCore.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings) in ODataQueryOption.cs + result = ApplyPaging(result, querySettings); Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions) in EnableQueryAttribute.cs + return queryOptions.ApplyTo(queryable, _querySettings); Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ExecuteQuery(object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, HttpRequest request) in EnableQueryAttribute.cs + queryable = ApplyQuery(queryable, queryOptions); Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuted(ActionExecutedContext actionExecutedContext, object responseValue, IQueryable singleResultCollection, ControllerActionDescriptor actionDescriptor, HttpRequest request) in EnableQueryAttribute.cs + object queryResult = ExecuteQuery(responseValue, singleResultCollection, actionDescriptor, request); Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuted(ActionExecutedContext actionExecutedContext) in EnableQueryAttribute.cs + object queryResult = OnActionExecuted( Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) Microsoft.AspNetCore.OData.Batch.ODataBatchMiddleware.Invoke(HttpContext context) in ODataBatchMiddleware.cs + await _next(context).ConfigureAwait(false); Microsoft.AspNetCore.OData.Query.ODataQueryRequestMiddleware.Invoke(HttpContext context) in ODataQueryRequestMiddleware.cs + await _next(context).ConfigureAwait(false); Microsoft.AspNetCore.OData.Routing.ODataRouteDebugMiddleware.Invoke(HttpContext context) in ODataRouteDebugMiddleware.cs + await _next(context).ConfigureAwait(false); Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Same here. $expand is also causing the same issue.
Same issue with oData 8.0.1
I also have same issue with OData 8.0.1. After some trial and error I did find that by removing the [EnableQuery] attribute (but keeping the [ODataAttributeRouting] attribute), I was able to retrieve all columns without error, so at least I can use my solution, but without the benefit of selecting columns..
A further note on this: - I managed to get around the error by creating a new .Net 5 project with parallel .Net EF Context that uses the .Net4.8 model. Not ideal, but it got me going again. I am not able to upgrade the base project as it references other (older) libraries. Had to change some of my entities a bit (particularly around the different [key attribute] handling between EF and EF Core), but didn't take too long to implement - once I worked out what to do. Hopefully this helps someone else get around it.
Are expands working properly for you? I can't seem to get the expand depth beyond 1 level
This is more detail on my issue (in the hopes you can see something I missed) https://github.com/OData/AspNetCoreOData/issues/248
Any news?
I'm also waiting for a reply since 22 May :-)
I created a fork with the modified version (change ef core to ef6) here: https://github.com/cyril-iselin/AspNetCoreOData
- Checkout Repo
- Run OdataRoutingSample
Query which doesnt work:
- http://localhost:64771/v1/Customers?$select=Name
- http://localhost:64771/Products?$filter=Id%20eq%202&$expand=Detail
Query which are working:
- http://localhost:64771/v1/Customers
- http://localhost:64771/v1/Customers?$filter=name%20eq%20%27Jonier%27
- http://localhost:64771/Products?$filter=Id%20eq%202
Thanks for helping.
I have the same problem, I have opened an Issue, hopefully it's going to be fixed soon https://github.com/OData/AspNetCoreOData/issues/367
In our project we have EF 6.4.4 and Data 8.0.4 and same issue ('Microsoft.OData.Edm.IEdmModel'. Only primitive types or enumeration types are supported in this context.) when we try to use expand feature. Do you have any plan for fixing that bug?
Do we have any update to this on the number of issues that are open here? I'm also affected by this.
Too many issues open with similar errors and this one really lacks proper details. Would be nice if you guys could unify all these issues into one if they are all the same problem.
Also, I don't personally understand the EntityFramework mentions here. As far as I'm aware, OData is completely oblivious to EF so I can't see how EF would have any impact on OData functionality.
All I know is that I'm currently using EF6.4.4 with the latest OData (Microsoft.AspNetCore.OData 8.0.7). When I attempt to query an endpoint with $expand, I get the error listed above. I did not have this problem in OData 7 and below.
I do agree that this appears to be duplicates with #367 and #380, but I'm trying to update to the latest version and this is a deal breaker if it does not work.
@julealgon Incidents #380 describes exactly the problem. And it is relevant to EF6 for sure. I gave look to the odata source code and there is a specific handling for EF6
@theentropic I‘ve managed to solve the $expand issue by declaring the objects wish to expand as Complex Types and remove $expand completely. $select does not work. It is amazing how oData does not offer any more a projection method.
I gave look to the odata source code and there is a specific handling for EF6
This is very surprising to hear @athinadev . I wonder why that is the case at all. Thanks for letting me know!
We exposed the functionality to replace/customize OData query LINQ expression. Anyone can try that to build your own LINQ Expression?
Do you have an example of how to override this? I'd be happy to implement it on my end, or is this simply overriding the ApplyQuery function in the EnableQueryAttribute?
The root cause is from the following changes:
https://github.com/OData/AspNetCoreOData/commit/96abeffdb3c3270a49f0a47c3b90668b0900a5a2

By design, we'd target 8.x to EF Core only.
Well thank you for the bad news. You could at least document this as breaking change. We could migrate to EFCore, but there oData has another Issue and the GroupBy raises an error. I think it’s time to abandon oData.
@xuzhg Thanks for identifying the breaking change. Forgive my ignorance, I'm unfamiliar with the OData implementation, but was this a conscious decision and made of necessity? If so, is OData 8's compatibility with EF documented somewhere? Can it be please?
If by chance compatibility with EF6 was inadvertently broken, given the issues with EFCore and Groupby, OData users (well this user at least, but I suspect there are others...) would very much like OData to remain compatible with EF6 for as long as it takes to address the group by issue. Is there a way this can be achieved?
If not my reading of this is that for anyone wanting to continue using odata $apply groupby with EF will be stuck on OData 7.x and EF6. As @athinadev indicates, this is disappointing.
@cam-m @athinadev It may not be perfect, but I've managed to hack back in support for EF6 in OData 8. I plan on wrapping the code up in a nuget module and publishing it on github. I will ping you here if you're interested when it's ready.
@cam-m Yes of course I am interested!!! Please let me know when is fixed
thanks in advance
@theentropic I'm interested too :). May you can make a PR to this repository? Then the odata team must not document that they have broken ef6 support since more then one year :)
@theentropic Good on you for that! I'm interested of course but am a bit hamstrung by my project as to which nuget packages I can use - so for me a pull request to this repo is ideal. I'm sure others will appreciate it though.
I'll see what I can do in terms of a pull request, the way I currently implemented it replaces some of the services, so would need to figure out what to do there.
Any news? Or an official statement that EF 6 is not supported anymore? @xuzhg
Or an official statement that EF 6 is not supported anymore?
As far as I know, this has already been confirmed. If you need EF6 support for now, I'd stick with OData v7.
Or an official statement that EF 6 is not supported anymore?
As far as I know, this has already been confirmed. If you need EF6 support for now, I'd stick with OData v7.
Where has it been confirmed? Here in the comments of this issue or elsewhere?
We've established OData7/EF6 as the technical option. The points remaining to be addressed are, a) was this intentional? b) if not can support be fixed and c) if so, can it be documented clearly (on the releases page) so people don't unwittingly go down this track.
I had the same issues as mentioned in the other posts. After many many ours of trying all sort of things I got it working. I downgraded from 8.0.10 to 7.5.10 and then it started working. At first I downgraded to 7.5.15 but this conflicted with another Microsoft package. Beside this downgrade I changed nothing.
Glad that I got it working but it's a bit disappointing to see how this bug/feature is treated.
Hope I save someone all the ours I waisted!!
@paulschalkwijk to late. After migrating 240 projects from .Net Framework WebApi.Odata to net6 AspNetCore.OData 8 I found this issue with EF6. Now i must downgrade to 7.x. Disappointing.