-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Change tracking throws InvalidCastException when enum is bound to tinyint in Sqlite #16111
Comments
@ArrowCase SQLite doesn't have a column type Note for triage: this happens because when picking a value conversion we reject it if it would not result in the correct mapping for the type specified. But since in this case the type specified is never correct, we will never accept the conversion. I'm not sure there is a good way to deal with this, but maybe we can have one behavior for store types we know, and a different one for store types we don't know. |
My code was originally written for LocalDB, and I switched providers to Sqlite thinking I shouldn't have to worry about the column annotations since Sqlite understands those data types even though it doesn't actually use them. In this case, the enum column is created just fine with INTEGER affinity. It seems like a bad experience that the tinyint annotation is acceptable for creating and reading from the column, but not for updating it, due to this issue in change tracking. |
@ArrowCase Thanks for the additional info. Note from triage: we should discuss with @bricelam |
@bricelam to explain the difference between "supported types" and "type affinity". |
SQLite supports four types: INTEGER, REAL, TEXT & BLOB. It uses a type affinity to determine the preferred way the data for a column should be stored on disk. But it also supports dynamic typing, so if converting to that type affinity would result in data loss, it won't be used. We use those same affinity rules here to determine a suitable CLR type when reverse engineering a model. (#8824 is about picking an even better CLR type by sampling the data) |
Fixes #16111 The issue was that when finding a type mapping based on type name affinity we were not checking that it was compatible with the CLR type. This resulted in short-circuiting of the conversion selection and hence the wrong mapping.
Fixes #16111 The issue was that when finding a type mapping based on type name affinity we were not checking that it was compatible with the CLR type. This resulted in short-circuiting of the conversion selection and hence the wrong mapping.
Fixes #16111 The issue was that when finding a type mapping based on type name affinity we were not checking that it was compatible with the CLR type. This resulted in short-circuiting of the conversion selection and hence the wrong mapping.
Fixes #16111 The issue was that when finding a type mapping based on type name affinity we were not checking that it was compatible with the CLR type. This resulted in short-circuiting of the conversion selection and hence the wrong mapping.
Versions
Windows 10
Visual Studio
16.2 Preview 1
.NET Core SDK
3.0.100-preview6-012264
NETCore.App
3.0.0-preview6-27804-01
Microsoft.EntityFrameworkCore.Sqlite
3.0.0-preview6.19304.10
Steps to reproduce
long
.tinyint
column.SaveChanges()
.Full repro gist here.
Note: this bug reproduces if the base type of the enum is explicitly set to something other than
long
, or if it is left as the implicit default ofint
.Expected result
The record is created with no errors.
Actual result:
The database is created successfully with a tinyint (INTEGER affinity) data type, but attempting to save changes after adding the entity fails:
It seems strange that change tracking needs to cast the enum to Int64 to compare it, but it's even stranger that the cast can somehow fail.
The text was updated successfully, but these errors were encountered: