-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
InvalidCastException when casting from one value type to another in a simple select statement #8652
Comments
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing.
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing. Also added support for translating Negate expression, which was previously evaluated on the client.
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing. Also added support for translating Negate expression, which was previously evaluated on the client.
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing. Also added support for translating Negate expression, which was previously evaluated on the client.
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing. Also added support for translating Negate expression, which was previously evaluated on the client.
…to another in a simple select statement Problem was for queries with value types being projected in a select expression when also using convert. The problem was that getValue is typed as object which then was converted to an expected type. However if the value returned by SQL was not exactly the same type, exception would get thrown due to boxing/unboxing. Fix is to detect when we apply convert on a top level projection, and in this case use explicit cast, so that type returned by SQL was exactly the same as the type that was expected after unboxing. Also added support for translating Negate expression, which was previously evaluated on the client.
fixed in 44e7316 |
I'm seeing this in 2.0.3 preview. The following will throw an InvalidCastException. Worked fine in 1.1
|
@natelaff Is this something that worked for you in 2.0.0 but is now failing in 2.0.3 preview? Can you post or link to a full project or code listing that demonstrates the issue so we can investigate it? |
@ajcvickers I'm uncertain. There were so many regressions in 2.0 that I couldn't even get this far into migrating my app until now. I will try to repro in a clean project. |
@maumar Can you please investigate this? |
I verified this is a bug in the current bits, but it's not a regression from 2.0. The bug is not related to this one, so I will file a new issue to track this. workaround is to perform the multiplication and sum on the client (it would be done so anyway, because we don't know how to translate GetValueOrDefault - will file an issue for this also) here is the code that should work: public async Task<decimal> GetSubtotalTotalAsync(string cartId)
{
using (var ctx = new MyContext())
{
var result = await ctx.CartItems
//.Include(c => c.ProductVariant) - include was not needed here navigation access will do this automatically
.Where(c => c.CartId == cartId)
.Select(c => new { Price = c.ProductVariant.Price, c.Quantity })
.ToListAsync();
return result
.Select(c => c.Price.GetValueOrDefault() * c.Quantity)
.Sum();
}
} |
…r decimal to float cast Problem was that as part of fixing #8652 we were removing explicit casts when processing result operators. This is fine for most aggregate operators, but is not correct for Min/Max. This is because the final result type is the same as the argument - original type of the argument must be preserved or we risk type mismatches in the final result. Additionally improved the fix for #1251 - we should be stripping order by clauses for Min/Max operators as well. Previously we exempt all ChoiceResultOperatorBase, instead of correct First/Single/Last.
…r decimal to float cast Problem was that as part of fixing #8652 we were removing explicit casts when processing result operators. This is fine for most aggregate operators, but is not correct for Min/Max. This is because the final result type is the same as the argument - original type of the argument must be preserved or we risk type mismatches in the final result. Additionally improved the fix for #1251 - we should be stripping order by clauses for Min/Max operators as well. Previously we exempt all ChoiceResultOperatorBase, instead of correct First/Single/Last.
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:
Limit__c
andSlots__c
are nullable doublesThe SQL profiler does not show any casting before the exception is thrown.
The same query was working in EF 6.x (Full Framework).
Steps to reproduce
decimal(18,0),null
and anint
primary key.Program.cs
.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
The text was updated successfully, but these errors were encountered: