Skip to content
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

Missing implicit numeric cast of decimal to integer in C# record #1933

Open
DottorPagliaccius opened this issue Jul 7, 2023 · 4 comments
Open

Comments

@DottorPagliaccius
Copy link

DottorPagliaccius commented Jul 7, 2023

Hi, I've found that Dapper behaves differently when using plain classes or records (working on Oracle 12).

When getting results from a command, like

return await connection.QueryAsync<SomeObject>(query);

this

public class SomeObject
{
    public int Id { get; set; }
}

works fine while this

public record SomeObject(int Id)

throws

System.InvalidOperationException: A parameterless default constructor or one matching signature (System.Decimal ID) is required for SomeNamespace.SomeObjectmaterialization

If I change property data type, like this

public record SomeObject(decimal Id)

it works, but I don't want to use decimal instead of int.

@DottorPagliaccius
Copy link
Author

Anyone? :/

@mgravell
Copy link
Member

mgravell commented Sep 2, 2023

Well, the good news is that in DapperAOT this should work identically in the two modesb- but DapperAOT is dependent on new compiler features in the net8 release (note: it is not dependent on net8 itself - just the build tools / build SDK). The constructor path in vanilla Dapper is ... limited. I'll take a look later to see what the current state is.

@burnchar
Copy link

burnchar commented Dec 6, 2023

Your Oracle number is probably unconstrained, e.g. NUMBER instead of NUMBER(9,0).
This seems to always map to System.Decimal even if the query rounds or casts the number.

For example, this errors unless the destination object has System.Decimal for some_column:
SELECT CAST (round(some_unconstrained_number, 3) AS NUMBER(18,15)) some_column FROM dual

I have never found a workaround for this other than modifying the structure of the table.

@burnchar
Copy link

burnchar commented Dec 6, 2023

Correction, I do have some code that uses Oracle's TO_BINARY_DOUBLE() function in the SQL, which does map to a System.Double. This is not great as the SQL needs to be modified, but works when you cannot change the database structure, which is often.
It would be preferable for the mapper to map any number type to System.Double and throw an exception if the contents do not fit, but I understand this is not possible from an earlier discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants