Commit c7ed6ec7 authored by Marc Gravell's avatar Marc Gravell

Fix #524 - `GridReader` should use the same conversion code as the regular reader

parent c3beb607
...@@ -141,7 +141,7 @@ public void Issue524_QueryMultiple_Cast() ...@@ -141,7 +141,7 @@ public void Issue524_QueryMultiple_Cast()
{ // aka: Read<int> should work even if the data is a <long> { // aka: Read<int> should work even if the data is a <long>
// using regular API // using regular API
connection.Query<int>("select cast(42 as bigint)").IsEqualTo(42); connection.Query<int>("select cast(42 as bigint)").Single().IsEqualTo(42);
connection.QuerySingle<int>("select cast(42 as bigint)").IsEqualTo(42); connection.QuerySingle<int>("select cast(42 as bigint)").IsEqualTo(42);
// using multi-reader API // using multi-reader API
......
...@@ -181,7 +181,7 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered) ...@@ -181,7 +181,7 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
} }
else else
{ {
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity); var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity, type);
if (buffered) result = result.ToList(); // for the "not a DbDataReader" scenario if (buffered) result = result.ToList(); // for the "not a DbDataReader" scenario
return Task.FromResult(result); return Task.FromResult(result);
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq; using System.Linq;
using System.Globalization;
namespace Dapper namespace Dapper
{ {
partial class SqlMapper partial class SqlMapper
...@@ -161,7 +161,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered) ...@@ -161,7 +161,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
cache.Deserializer = deserializer; cache.Deserializer = deserializer;
} }
IsConsumed = true; IsConsumed = true;
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity); var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity, type);
return buffered ? result.ToList() : result; return buffered ? result.ToList() : result;
} }
...@@ -184,8 +184,16 @@ private T ReadRow<T>(Type type, Row row) ...@@ -184,8 +184,16 @@ private T ReadRow<T>(Type type, Row row)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false)); deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer; cache.Deserializer = deserializer;
} }
result = (T) deserializer.Func(reader); object val = deserializer.Func(reader);
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row); while (reader.Read()) { } if(val == null || val is T)
{
result = (T)val;
} else {
var convertToType = Nullable.GetUnderlyingType(type) ?? type;
result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
}
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row);
while (reader.Read()) { }
} }
else if((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one else if((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one
{ {
...@@ -297,13 +305,19 @@ public IEnumerable<TReturn> Read<TReturn>(Type[] types, Func<object[], TReturn> ...@@ -297,13 +305,19 @@ public IEnumerable<TReturn> Read<TReturn>(Type[] types, Func<object[], TReturn>
return buffered ? result.ToList() : result; return buffered ? result.ToList() : result;
} }
private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> deserializer, Identity typedIdentity) private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> deserializer, Identity typedIdentity, Type effectiveType)
{ {
try try
{ {
var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
while (index == gridIndex && reader.Read()) while (index == gridIndex && reader.Read())
{ {
yield return (T)deserializer(reader); object val = deserializer(reader);
if (val == null || val is T) {
yield return (T)val;
} else {
yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
}
} }
} }
finally // finally so that First etc progresses things even when multiple rows finally // finally so that First etc progresses things even when multiple rows
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment