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

Left joined nullable fields causing conversion issue #17

Closed
79it opened this issue May 28, 2013 · 4 comments
Closed

Left joined nullable fields causing conversion issue #17

79it opened this issue May 28, 2013 · 4 comments

Comments

@79it
Copy link

79it commented May 28, 2013

I use Entity Framework mappings with NPoco and I have a view using a left join. The numeric fields on the joined table are represented as nullable which causes a problem in NPoco when converting the data.

A typical error looks like this:

Invalid cast from 'System.UInt32' to 'System.Nullable`1[[System.Int64]]

My solution is a SafeConvert method which gets the underlying type and uses that to convert the data instead.

On line 448 of PocoData.cs I changed:

converter = src => Convert.ChangeType(src, dstType, null);

to:

converter = src => SafeConvert(dstType, src);

and the method looks like this:

private static object SafeConvert(Type dstType, object src)
{
    var origType = Nullable.GetUnderlyingType(dstType) ?? dstType;
    return src == null ? null : Convert.ChangeType(src, origType, null);
}

I haven't tested this to destruction yet but I'll let you know if I run into any problems while developing the rest of my application.

If this fix could be added to the next build that would be appreciated.

Thanks

Chris

@schotime
Copy link
Owner

Hey Chris,

Thanks for the bug report.
Could you provide me with some more information (or some code) that describes the exact problem so that I can create a test for it.

Cheers,
Adam

@79it
Copy link
Author

79it commented May 29, 2013

After bit more research, it appears to affect only members with Nullable type.

I'm using MySQL as the database and columns causing this issue are defined in the database as INT(10) UNSIGNED NOT NULL.

Types interpreted as DECIMAL, FLOAT, DOUBLE, INT and STRING do not seem to cause a problem.

When such a field is used on the left side of a left join it could null so Entity Framework will set up this field as Nullable rather than just long.

Because the property is defined as nullable, when dstType is passed to Convert.ChangeType it is reading Nullable rather than the underlying data type and any non-null value causes a problem.

My SafeConvert method gets the underlying data type and uses that if the value is not null or returns null if the value is null.

I set up a simple test like this (obviously an ID column would not usually be null - in this case remember it was defined like this because it was on the left side of the join). I have included decimal and int types to show these do not cause the problem:

POCO:

public class test
{
    public Nullable<long> ItemID { get; set; }
    public string Code { get; set; }
    public string ItemName { get; set; }
    public Nullable<decimal> Price { get; set; }
    public Nullable<int> Stock { get; set; }
}

Request:

List<test> myModel = db.Fetch<test>("select * from content");

If you change public Nullable ItemID { get; set; } to public long ItemID { get; set; } you won't get the problem.

Please let me know if you need more info.

Thanks

Chris

@schotime
Copy link
Owner

Hi Chris,

I have managed to reproduce this and fix it with your suggestions.
Please checkout 2.1.23-beta on NuGet to see if it now works.

Cheers,
Adam

@79it
Copy link
Author

79it commented May 30, 2013

I just downloaded the latest branch and so far so good.

Thanks for the speedy fix.

Chris

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

2 participants