Description
InvalidCastApp.zip
When casting a property from a nullable double to a nullable int in a Select
function, an InvalidCastException occurs. Likewise, the same exception occurs if the types are not nullable.
Attached is a working example of the issue. Just create the database and table first and then update the connection string in Program.cs
.
The select looks like this:
.Select(o => new DTO() {
Limit = o.Limit__c.HasValue ? (int?)o.Limit__c : null,
Slots = o.Slots__c.HasValue ? (int?)o.Slots__c : null
})
.Where(o => cIds.Contains(o.CId))
.ToListAsync());
Limit__c
and Slots__c
are nullable doubles
The SQL profiler does not show any casting before the exception is thrown.
The same query was working in EF 6.x (Full Framework).
Exception message: Specified cast is not valid.
Stack trace:
<error errorId="7f262bc2-3b41-439b-be10-ed2c6e480a0f" application="/LM/W3SVC/2/ROOT" host="" type="System.InvalidCastException" message="Specified cast is not valid." source="Anonymously Hosted DynamicMethods Assembly" detail="System.InvalidCastException: Specified cast is not valid.;
at lambda_method(Closure , QueryContext , ValueBuffer );
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ProjectionShaper.TypedProjectionShaper`3.Shape(QueryContext queryContext, ValueBuffer valueBuffer);
at Microsoft.EntityFrameworkCore.Query.AsyncQueryMethodProvider.<>c__DisplayClass3_0`1.<_ShapedQuery>b__0(ValueBuffer vb);
at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.<MoveNextCore>d__7.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Linq.AsyncEnumerable.AsyncIterator`1.<MoveNext>d__10.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Linq.AsyncEnumerable.<Aggregate_>d__6`3.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult();
at --snip--.<WithContext>d__5`1.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult();
at --snip--.<GetByContractIds>d__13.MoveNext();--- End of stack trace from previous location where exception was thrown ---;
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult();
at --snip--d__54.MoveNext() in
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult();
at --snip--Load>d__14.MoveNext() in
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.GetResult();
at --snip--Contract>d__70.MoveNext() in
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task);
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task);
at System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d();
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f();
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c();
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult);
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState);
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult);
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult);
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult);
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult);
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState);
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult);
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult);
at System.Web.HttpApplication.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar)" user="" time="2017-05-31T19:14:36.8015246Z">
Steps to reproduce
- Create a table with a column defined as
decimal(18,0),null
and anint
primary key. - Use the project in the attached zip, first updating the connection string in
Program.cs
. - Running the application will give the invalid cast exception.
.Select(o => new DTO() {
ModelWithNullableInt = o.ModelWithNullableDecimal.HasValue ? (int?)o.ModelWithNullableDecimal: null})
Further technical details
EF Core version: Reproduced in 1.1.2 as well as 2.0.0-preview1-final
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 64-bit
IDE: Visual Studio 2017 - build 26510.0 Preview