提交 c7ed6ec7 编写于 作者: M Marc Gravell

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

上级 c3beb607
......@@ -141,7 +141,7 @@ public void Issue524_QueryMultiple_Cast()
{ // aka: Read<int> should work even if the data is a <long>
// 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);
// using multi-reader API
......
......@@ -181,7 +181,7 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
}
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
return Task.FromResult(result);
}
......
......@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Globalization;
namespace Dapper
{
partial class SqlMapper
......@@ -161,7 +161,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
cache.Deserializer = deserializer;
}
IsConsumed = true;
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity);
var result = ReadDeferred<T>(gridIndex, deserializer.Func, typedIdentity, type);
return buffered ? result.ToList() : result;
}
......@@ -184,8 +184,16 @@ private T ReadRow<T>(Type type, Row row)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer;
}
result = (T) deserializer.Func(reader);
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row); while (reader.Read()) { }
object val = deserializer.Func(reader);
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
{
......@@ -297,13 +305,19 @@ public IEnumerable<TReturn> Read<TReturn>(Type[] types, Func<object[], TReturn>
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
{
var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册