-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Repro:
var query = from Post p in ctx.Posts
select p.PostId;
var result = query.ToList();
the compiler introduces a Cast() (because type of "p" has been explicitly specified) relinq turns this into a subquery like so:
from p in { from p' in ctx.Post select p' => Cast<Post>() } select p.PostId
then we lift the subquery:
from p in ctx.Posts select p.PostId => Cast<Post>()
this fails with the following:
Unhandled Exception: System.InvalidOperationException: No coercion operator is defined between types 'System.Int32' and 'Repro3499.Post'.
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 Remotion.Linq.Clauses.ResultOperators.CastResultOperator.GetOutputDataInfo(IStreamedDataInfo inputInfo)
at Remotion.Linq.QueryModel.b__0(IStreamedDataInfo current, ResultOperatorBase resultOperator)
at System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func3 func)
at Remotion.Linq.QueryModel.GetOutputDataInfo()
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.SingleResultToSequence(QueryModel queryModel) in D:\k\EntityFramework\src\EntityFramework.Core\Query\EntityQueryModelVisitor.cs:line 249
at Microsoft.Data.Entity.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel) in D:\k\EntityFramework\src\EntityFramework.Core\Query\EntityQueryModelVisitor.cs:line 163
at Microsoft.Data.Entity.Storage.Database.CompileQuery[TResult](QueryModel queryModel) in D:\k\EntityFramework\src\EntityFramework.Core\Storage\Database.cs:line 68
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass19_01.<CompileQuery>b__0() in D:\k\EntityFramework\src\EntityFramework.Core\Query\Internal\QueryCompiler.cs:line 183 at Microsoft.Data.Entity.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler) in D:\k\EntityFramework\src\EntityFramework.Core\Query\Internal\CompiledQueryCache.cs:line 32
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.CompileQuery[TResult](Expression query) in D:\k\EntityFramework\src\EntityFramework.Core\Query\Internal\QueryCompiler.cs:line 138
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.Execute[TResult](Expression query) in D:\k\EntityFramework\src\EntityFramework.Core\Query\Internal\QueryCompiler.cs:line 84
at Microsoft.Data.Entity.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) in D:\k\EntityFramework\src\EntityFramework.Core\Query\Internal\EntityQueryProvider.cs:line 37
at Remotion.Linq.QueryableBase1.GetEnumerator() at System.Collections.Generic.List1..ctor(IEnumerable`1 collection)
In this case the cast is redundant, but if we project a property from a derived type like so:
from VipCustomer c in ctx.Customers
select c.SomeVipCustomerProperty
the cast needs to be preserved