WebApi
WebApi copied to clipboard
Lambda Error: No coercion operator is defined between types
System.InvalidOperationException
HResult=0x80131509
Message=No coercion operator is defined between types 'Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAllAndExpand1[Api.Odata.OpsTenant]' and 'Api.Odata.OpsTenant'. Source=System.Linq.Expressions StackTrace: at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType) at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method) at System.Linq.Expressions.Expression.Convert(Expression expression, Type type) at Remotion.Linq.Clauses.ResultOperators.CastResultOperator.GetOutputDataInfo(IStreamedDataInfo inputInfo) at Remotion.Linq.QueryModel.<>c.<GetOutputDataInfo>b__10_0(IStreamedDataInfo current, ResultOperatorBase resultOperator) at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable
1 source, TAccumulate seed, Func3 func) at Remotion.Linq.QueryModel.GetOutputDataInfo() at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger
1 logger, Type contextType)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass13_01.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func
1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) at Remotion.Linq.QueryableBase
1.GetEnumerator()
at System.Collections.Generic.LargeArrayBuilder1.AddRange(IEnumerable
1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source) at System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 source)
at Api.Odata.Web.Controllers.OpsTenantController.Get(ODataQueryOptions`1 options) in C:\Work\Source.Backend\Api.Odata.Web\Controllers\OpsTenantController.cs:line 49
The underlying code is:
var qry1 = Repository.OpsTenant
.Take(10)
.Include(x => x.Buildings)
.ProjectTo<Api.Odata.OpsTenant>(x => x.Buildings);
var qry1a = options.ApplyTo(qry1).Cast<Api.Odata.OpsTenant>();
and leads to the following lambda (note: ProjectTo is totally removed):
.Call System.Linq.Queryable.Cast(.Call System.Linq.Queryable.Select(
.Call System.Linq.Queryable.Take(
.Call System.Linq.Queryable.OrderBy(
.Call System.Linq.Queryable.Select(
.Call Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include(
.Call System.Linq.Queryable.Take(
.Constant<Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[Data.Core.OpsTenant]>(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable
1[Data.Core.OpsTenant]),
10),
'(.Lambda #Lambda1<System.Func2[Data.Core.OpsTenant,System.Collections.Generic.ICollection
1[Data.Core.CoreBuilding]]>))
,
'(.Lambda #Lambda2<System.Func2[Data.Core.OpsTenant,Api.Odata.OpsTenant]>)), '(.Lambda #Lambda3<System.Func
2[Api.Odata.OpsTenant,System.Guid]>)),
.Constant<Microsoft.AspNet.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer1[System.Int32]>(Microsoft.AspNet.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer
1[System.Int32]).TypedProperty)
,
'(.Lambda #Lambda4<System.Func2[Api.Odata.OpsTenant,Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAllAndExpand
1[Api.Odata.OpsTenant]]>))
)
.Lambda #Lambda1<System.Func2[Data.Core.OpsTenant,System.Collections.Generic.ICollection
1[Data.Core.CoreBuilding]]>(Data.Core.OpsTenant $x)
{
$x.Buildings
}
.Lambda #Lambda2<System.Func2[Data.Core.OpsTenant,Api.Odata.OpsTenant]>(Data.Core.OpsTenant $dtoOpsTenant) { .New Api.Odata.OpsTenant(){ Identity = $dtoOpsTenant.Identity, Name = $dtoOpsTenant.Name, Buildings = .Call System.Linq.Enumerable.ToList(.Call System.Linq.Enumerable.Select( $dtoOpsTenant.Buildings, .Lambda #Lambda5<System.Func
2[Data.Core.CoreBuilding,Api.Odata.CoreBuilding]>))
}
}
.Lambda #Lambda3<System.Func`2[Api.Odata.OpsTenant,System.Guid]>(Api.Odata.OpsTenant $$it) { $$it.Identity }
.Lambda #Lambda4<System.Func2[Api.Odata.OpsTenant,Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAllAndExpand
1[Api.Odata.OpsTenant]]>(Api.Odata.OpsTenant $var1)
{
.New Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAllAndExpand1[Api.Odata.OpsTenant](){ ModelID = "df7f2288-4d2c-44bc-9497-19bf3e69b983", Instance = $var1, UseInstanceForProperties = True, Container = .New Microsoft.AspNet.OData.Query.Expressions.PropertyContainer+NamedProperty
1[System.Collections.Generic.IEnumerable1[Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll
1[Api.Odata.CoreBuilding]]]()
{
Name = "Buildings",
Value = .Call System.Linq.Enumerable.Select(
$var1.Buildings,
.Lambda #Lambda6<System.Func2[Api.Odata.CoreBuilding,Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll
1[Api.Odata.CoreBuilding]]>)
}
}
}
.Lambda #Lambda5<System.Func`2[Data.Core.CoreBuilding,Api.Odata.CoreBuilding]>(Data.Core.CoreBuilding $dtoCoreBuilding) { .New Api.Odata.CoreBuilding(){ Identity = $dtoCoreBuilding.Identity, Name = $dtoCoreBuilding.LongName } }
.Lambda #Lambda6<System.Func2[Api.Odata.CoreBuilding,Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll
1[Api.Odata.CoreBuilding]]>(Api.Odata.CoreBuilding $var2)
{
.New Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll`1Api.Odata.CoreBuilding{
ModelID = "df7f2288-4d2c-44bc-9497-19bf3e69b983",
Instance = $var2,
UseInstanceForProperties = True
}
}
Looksl ike both, a N+1 problem (doo many hardcoded subqueries) as well as definitely an error in the generated lambda.
And 5 months later: Assigned, not worked on.
Just as update - it is STILL there and it still blocks using Odata in custom Lambda.
It's been already much more than 5 months. I'm getting similar error with a following code:
var results = this.repository.GetAll().Where(u => u.IsBanned);
return options.ApplyTo(results).Cast<UserEntity>().AsQueryable().
EDIT: With following code too:
var results = this.repository.GetAll()
return options.ApplyTo(results).Cast<UserEntity>().AsQueryable().
@mikepizzo any updates on this?
I really do appreciate the teams stance of "maybe if we ignore it, it will go away".
The astounding thing about this is that this is an incredibly simplistic use case, and yet OData does not support it.
Still an issue!
I am having the same problem. I can't select, expand. Anyone found a solution to this problem?
public async Task<ActionResult<IQueryable<ProductODataDTO>>> Get(ODataQueryOptions<ProductODataDTO> oDataQueryOpts)
{
var products = _genericReadRepository.GetAll<Product>().ProjectToType<ProductODataDTO>();
var odataQueryFilter = oDataQueryOpts.ApplyTo(products.AsQueryable()).Cast<ProductODataDTO>();
return Ok(odataQueryFilter.ToList());
}
netcoreapp3.1 OData 7.5.7
We progressed most of the project with Odata. It would be very disappointing to take it back. Help please!
@xuzhg -- can you take a look at this? note latest repro is w/.net 6 and aspnetcore odata 8.0.10.
@burakkaradag -- I was just noting that you said you had this issue with .net6.0 and OData 8.0.10 (so it's a current issue)
is this the repro? https://github.com/OData/AspNetCoreOData
ow no sory @mikepizzo
netcoreapp3.1 OData 7.5.7
I have the problem in this version I updated my first comment
hurray!
this method worked for me
before
[HttpGet]
[EnableQuery]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(List<SalesOrdersODataDTO>))]
public async Task<ActionResult<IQueryable<ProductODataDTO>>> Get(ODataQueryOptions<ProductODataDTO> oDataQueryOpts)
{
var products = _genericReadRepository.GetAll<Product>().ProjectToType<ProductODataDTO>();
var odataQueryFilter = oDataQueryOpts.ApplyTo(products.AsQueryable()).Cast<ProductODataDTO>();
return Ok(odataQueryFilter.ToList());
}
after
[HttpGet]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(List<SalesOrdersODataDTO>))]
public async Task<ActionResult<List<SalesOrdersODataDTO>>> Get(ODataQueryOptions<SalesOrdersODataDTO> oDataQueryOpts)
{
var salesOrders = _genericReadRepository.GetAll<SalesOrder>().ProjectToType<SalesOrdersODataDTO>();
var odataQueryFilter = oDataQueryOpts.ApplyTo(salesOrders.AsQueryable()) as IQueryable<dynamic>;
return Ok(odataQueryFilter.ToList());
}
EnableQuery attribute removed and used IQueryable<dynamic>
@mikepizzo Thank you also for your quick turnaround.