-
Notifications
You must be signed in to change notification settings - Fork 26
Mistreating ENUMs whenever they are backed by something else than int #309
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
Comments
Another example of an issue related to non-int fields:
Happens when accessing an referenced entity, which has a
The data model in question uses mapping on a legacy database. Stripped down version of the entities is as follows:
The code which causes the exception, processes the result of a query, which returns records encapsulating related entities, and is as follows: private record QueryProjection(…, DProduct Product, …);
|
Update: The second issue was caused by a mismatched primary key data type (short instead of int) in an entity referenced from See also: dotnet/runtime#19290 and source code here: https://github.com/dotnet/SqlClient/blob/73c6b2ff3ef3b55431cf187e72d5de918caccf76/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBuffer.cs#L409 |
Hello @ondrejtucny, thank you for the report, I'll look at these issues and be back with some investigation results or comments |
By the way, cast to integer may be connected with the fact that literal parameters are by default integer, for example here |
As far as I know .NET does the same thing, it casts short to int. What is 0 in the example above? Is it constant? What type it was on on the level of IQueryable query? |
Faced the same issue short enum failed on sql server (ShortEnumType : short)
Unable to cast object of type 'System.Int32' to type 'System.Int16'.
long enum is OK (LongEnumType : long)
|
The value 0 was provided as a compile time constant:
It would be better to analyze the expression tree and do own type decisions. C#'s and SQL's type compatibility rules don't match, SQL being IMO more permissive. Hence, for example, in case of comparison operators the types of operands are decided bottom-up, and only at the comparison level a decision is made whether injecting type casts is necessary or not. Similarly, in case of the binary operators (e.g. +, -), first the type of operands is discovered bottom-up, then a decision of the resulting type made at the operator level (e.g. short + int → int), and then a top-down type compatibility check is made, again inserting type casts if and only if necessary. This way I think you can get rid of most unwanted type casts. |
I am running into repeated issues whenever I work with
enum
fields which are backed by anything else butint
.This simple query:
causes an exception:
The inner exception is an "Ambiguous match found." error. And this is the stack trace:
I can try updating to the latest master, in a few days, to confirm this as a pending bug. However, I do believe this has a similar root cause as the mistreatment of non-int fields in general. I have seen DO generate casts in SQL queries, completely unnecessary, such as this:
…AND ( CAST([a].[id_arch] AS integer) = 0));
, whereid_arch
is asmallint
column (short
in C#).It's a pain and I hope @alex-kulakov and the team will pay attention to this. I already know how to write unit tests in DO codebase, so I will try contributing at least tests to identify these issues.
The text was updated successfully, but these errors were encountered: