-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
IDataReader.GetRowParser<string>() throws exception #1822
Comments
You're right: this is a bug (but FYI, this is not an "extra unboxing", just a downcast). The first thing is to write a unit test for it (in DataReaderTests): /// <summary>
/// See https://github.com/DapperLib/Dapper/issues/1822
/// </summary>
[Fact]
public void issue_number_1822()
{
var reader = connection.ExecuteReader("select 'test' as col");
var rowParser = reader.GetRowParser<string>();
reader.Read();
// This should not throw!
string result = rowParser(reader);
Assert.Equal("test", result);
} And it's awfully red. My firt idea to fix it was simply to rewrite public static Func<IDataReader, T> GetRowParser<T>(this IDataReader reader, Type concreteType = null,
int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false)
{
concreteType ??= typeof(T);
var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing);
// Always use a wrapper: this works for value and ref types (delegate casting is not an option).
return _ => (T)func(_);
} Instead of: public static Func<IDataReader, T> GetRowParser<T>(this IDataReader reader, Type concreteType = null,
int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false)
{
concreteType ??= typeof(T);
var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing);
if (concreteType.IsValueType)
{
return _ => (T)func(_);
}
else
{
return (Func<IDataReader, T>)(Delegate)func;
}
} But unfortunately, this breaks the public static Func<IDataReader, T> GetRowParser<T>(this IDataReader reader, Type concreteType = null,
int startIndex = 0, int length = -1, bool returnNullIfFirstMissing = false)
{
concreteType ??= typeof(T);
var func = GetDeserializer(concreteType, reader, startIndex, length, returnNullIfFirstMissing);
if (func.Method.ReturnType != typeof(T))
{ // Always use a wrapper: this works for value and ref types (delegate casting is not an option).
return _ => (T)func(_);
}
return (Func<IDataReader, T>)(Delegate)func;
} I'll submit a PR asap. |
Just ran into this bug. Thanks for fixing @olivier-spinelli |
Using .NET Core 6
Dapper v 2.0.123
Throws exception:
works, but then extra unboxing is needed:
string result = (string)rowParser(reader)
The text was updated successfully, but these errors were encountered: