Skip to content

Commit 2b7b3fe

Browse files
authored
Merge pull request #1575 from zqlovejyc/main
2 parents 61a0434 + 600c1ac commit 2b7b3fe

File tree

4 files changed

+41
-24
lines changed

4 files changed

+41
-24
lines changed

Dapper/SqlMapper.GridReader.Async.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Data.Common;
5+
using System.Globalization;
56
using System.Linq;
67
using System.Threading;
78
using System.Threading.Tasks;
@@ -178,7 +179,7 @@ private Task<IEnumerable<T>> ReadAsyncImpl<T>(Type type, bool buffered)
178179
else
179180
{
180181
var result = ReadDeferred<T>(gridIndex, deserializer.Func, type);
181-
if (buffered) result = result.ToList(); // for the "not a DbDataReader" scenario
182+
if (buffered) result = result?.ToList(); // for the "not a DbDataReader" scenario
182183
return Task.FromResult(result);
183184
}
184185
}
@@ -210,7 +211,9 @@ private async Task<T> ReadRowAsyncImplViaDbReader<T>(DbDataReader reader, Type t
210211
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
211212
cache.Deserializer = deserializer;
212213
}
213-
result = (T)deserializer.Func(reader);
214+
215+
result = ConvertTo<T>(deserializer.Func(reader));
216+
214217
if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row);
215218
while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent rows */ }
216219
}
@@ -230,7 +233,7 @@ private async Task<IEnumerable<T>> ReadBufferedAsync<T>(int index, Func<IDataRea
230233
var buffer = new List<T>();
231234
while (index == gridIndex && await reader.ReadAsync(cancel).ConfigureAwait(false))
232235
{
233-
buffer.Add((T)deserializer(reader));
236+
buffer.Add(ConvertTo<T>(deserializer(reader)));
234237
}
235238
return buffer;
236239
}

Dapper/SqlMapper.GridReader.cs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Data;
44
using System.Linq;
55
using System.Globalization;
6+
using System.Runtime.CompilerServices;
7+
68
namespace Dapper
79
{
810
public static partial class SqlMapper
@@ -159,7 +161,7 @@ private IEnumerable<T> ReadImpl<T>(Type type, bool buffered)
159161
}
160162
IsConsumed = true;
161163
var result = ReadDeferred<T>(gridIndex, deserializer.Func, type);
162-
return buffered ? result.ToList() : result;
164+
return buffered ? result?.ToList() : result;
163165
}
164166

165167
private T ReadRow<T>(Type type, Row row)
@@ -181,16 +183,9 @@ private T ReadRow<T>(Type type, Row row)
181183
deserializer = new DeserializerState(hash, GetDeserializer(type, reader, 0, -1, false));
182184
cache.Deserializer = deserializer;
183185
}
184-
object val = deserializer.Func(reader);
185-
if (val == null || val is T)
186-
{
187-
result = (T)val;
188-
}
189-
else
190-
{
191-
var convertToType = Nullable.GetUnderlyingType(type) ?? type;
192-
result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
193-
}
186+
187+
result = ConvertTo<T>(deserializer.Func(reader));
188+
194189
if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row);
195190
while (reader.Read()) { /* ignore subsequent rows */ }
196191
}
@@ -360,18 +355,9 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese
360355
{
361356
try
362357
{
363-
var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
364358
while (index == gridIndex && reader.Read())
365359
{
366-
object val = deserializer(reader);
367-
if (val == null || val is T)
368-
{
369-
yield return (T)val;
370-
}
371-
else
372-
{
373-
yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
374-
}
360+
yield return ConvertTo<T>(deserializer(reader));
375361
}
376362
}
377363
finally // finally so that First etc progresses things even when multiple rows
@@ -433,6 +419,14 @@ public void Dispose()
433419
}
434420
GC.SuppressFinalize(this);
435421
}
422+
423+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
424+
private static T ConvertTo<T>(object value) => value switch
425+
{
426+
T typed => typed,
427+
null or DBNull => default,
428+
_ => (T)Convert.ChangeType(value, Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T), CultureInfo.InvariantCulture),
429+
};
436430
}
437431
}
438432
}

tests/Dapper.Tests/AsyncTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,16 @@ public async Task TestMultiAsync()
240240
}
241241
}
242242

243+
[Fact]
244+
public async Task TestMultiConversionAsync()
245+
{
246+
using (SqlMapper.GridReader multi = await connection.QueryMultipleAsync("select Cast(1 as BigInt) Col1; select Cast(2 as BigInt) Col2").ConfigureAwait(false))
247+
{
248+
Assert.Equal(1, multi.ReadAsync<int>().Result.Single());
249+
Assert.Equal(2, multi.ReadAsync<int>().Result.Single());
250+
}
251+
}
252+
243253
[Fact]
244254
public async Task TestMultiAsyncViaFirstOrDefault()
245255
{

tests/Dapper.Tests/QueryMultipleTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ public void TestQueryMultipleBuffered()
3131
}
3232
}
3333

34+
[Fact]
35+
public void TestMultiConversion()
36+
{
37+
using (SqlMapper.GridReader multi = connection.QueryMultiple("select Cast(1 as BigInt) Col1; select Cast(2 as BigInt) Col2"))
38+
{
39+
Assert.Equal(1, multi.Read<int>().Single());
40+
Assert.Equal(2, multi.Read<int>().Single());
41+
}
42+
}
43+
3444
[Fact]
3545
public void TestQueryMultipleNonBufferedIncorrectOrder()
3646
{

0 commit comments

Comments
 (0)