未验证 提交 2b7b3fe4 编写于 作者: N Nick Craver 提交者: GitHub

Merge pull request #1575 from zqlovejyc/main

......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
......@@ -178,7 +179,7 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
else
{
var result = ReadDeferred<T>(gridIndex, deserializer.Func, 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);
}
}
......@@ -210,7 +211,9 @@ private async Task<T> ReadRowAsyncImplViaDbReader<T>(DbDataReader reader, Type t
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer;
}
result = (T)deserializer.Func(reader);
result = ConvertTo<T>(deserializer.Func(reader));
if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row);
while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent rows */ }
}
......@@ -230,7 +233,7 @@ private async Task<IEnumerable<T>> ReadBufferedAsync<T>(int index, Func<IDataRea
var buffer = new List<T>();
while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false))
{
buffer.Add((T)deserializer(reader));
buffer.Add(ConvertTo<T>(deserializer(reader)));
}
return buffer;
}
......
......@@ -3,6 +3,8 @@
using System.Data;
using System.Linq;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace Dapper
{
public static partial class SqlMapper
......@@ -159,7 +161,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
}
IsConsumed = true;
var result = ReadDeferred<T>(gridIndex, deserializer.Func, type);
return buffered ? result.ToList() : result;
return buffered ? result?.ToList() : result;
}
private T ReadRow<T>(Type type, Row row)
......@@ -181,16 +183,9 @@ private T ReadRow<T>(Type type, Row row)
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
cache.Deserializer = deserializer;
}
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);
}
result = ConvertTo<T>(deserializer.Func(reader));
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row);
while (reader.Read()) { /* ignore subsequent rows */ }
}
......@@ -360,18 +355,9 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese
{
try
{
var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
while (index == gridIndex && reader.Read())
{
object val = deserializer(reader);
if (val == null || val is T)
{
yield return (T)val;
}
else
{
yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
}
yield return ConvertTo<T>(deserializer(reader));
}
}
finally // finally so that First etc progresses things even when multiple rows
......@@ -433,6 +419,14 @@ public void Dispose()
}
GC.SuppressFinalize(this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static T ConvertTo<T>(object value) => value switch
{
T typed => typed,
null or DBNull => default,
_ => (T)Convert.ChangeType(value, Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T), CultureInfo.InvariantCulture),
};
}
}
}
......@@ -240,6 +240,16 @@ public async Task TestMultiAsync()
}
}
[Fact]
public async Task TestMultiConversionAsync()
{
using (SqlMapper.GridReader multi = await connection.QueryMultipleAsync("select Cast(1 as BigInt) Col1; select Cast(2 as BigInt) Col2").ConfigureAwait(false))
{
Assert.Equal(1, multi.ReadAsync<int>().Result.Single());
Assert.Equal(2, multi.ReadAsync<int>().Result.Single());
}
}
[Fact]
public async Task TestMultiAsyncViaFirstOrDefault()
{
......
......@@ -31,6 +31,16 @@ public void TestQueryMultipleBuffered()
}
}
[Fact]
public void TestMultiConversion()
{
using (SqlMapper.GridReader multi = connection.QueryMultiple("select Cast(1 as BigInt) Col1; select Cast(2 as BigInt) Col2"))
{
Assert.Equal(1, multi.Read<int>().Single());
Assert.Equal(2, multi.Read<int>().Single());
}
}
[Fact]
public void TestQueryMultipleNonBufferedIncorrectOrder()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册