Skip to content

Commit 3b215e3

Browse files
committed
Merge pull request #415 from StackExchange/UseSingleResultSingleRow
Use single-row/single-result hint when possible
2 parents 65b26d6 + ec3a195 commit 3b215e3

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

Dapper.Tests/Assert.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ namespace Dapper.Tests
44
{
55
public static class Assert
66
{
7-
public static void IsEqualTo<T>(this T obj, T other)
7+
public static void IsEqualTo<T>(this T expected, T actual)
88
{
9-
Xunit.Assert.Equal(obj, other);
9+
Xunit.Assert.Equal(expected, actual);
1010
}
1111

1212
public static void IsSequenceEqualTo<T>(this IEnumerable<T> obj, IEnumerable<T> other)

Dapper/SqlMapper.Async.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
117117
try
118118
{
119119
if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false);
120-
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, cancel).ConfigureAwait(false);
120+
reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), cancel).ConfigureAwait(false);
121121

122122
var tuple = info.Deserializer;
123123
int hash = GetColumnHash(reader);
@@ -179,7 +179,7 @@ private static async Task<T> QueryFirstOrDefaultAsync<T>(this IDbConnection cnn,
179179
try
180180
{
181181
if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false);
182-
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, cancel).ConfigureAwait(false);
182+
reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow), cancel).ConfigureAwait(false);
183183

184184
T result = default(T);
185185
if(await reader.ReadAsync(cancel).ConfigureAwait(false))
@@ -547,7 +547,7 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TFirst, TSecond, T
547547
{
548548
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
549549
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
550-
using (var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false))
550+
using (var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), command.CancellationToken).ConfigureAwait(false))
551551
{
552552
if (!command.Buffered) wasClosed = false; // handing back open reader; rely on command-behavior
553553
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity, true);
@@ -594,7 +594,7 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbC
594594
try {
595595
if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false);
596596
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
597-
using (var reader = await cmd.ExecuteReaderAsync(command.CancellationToken).ConfigureAwait(false)) {
597+
using (var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), command.CancellationToken).ConfigureAwait(false)) {
598598
var results = MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, true);
599599
return command.Buffered ? results.ToList() : results;
600600
}
@@ -644,7 +644,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
644644
{
645645
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
646646
cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader);
647-
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false);
647+
reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess), command.CancellationToken).ConfigureAwait(false);
648648

649649
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache, command.CancellationToken);
650650
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
@@ -721,7 +721,7 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn,
721721
{
722722
cmd = (DbCommand)command.SetupCommand(cnn, paramReader);
723723
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
724-
var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false);
724+
var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess), command.CancellationToken).ConfigureAwait(false);
725725
wasClosed = false;
726726
return reader;
727727
}

Dapper/SqlMapper.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition
697697
{
698698
return QueryMultipleImpl(cnn, ref command);
699699
}
700+
700701
private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandDefinition command)
701702
{
702703
object param = command.Parameters;
@@ -710,7 +711,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
710711
{
711712
if (wasClosed) cnn.Open();
712713
cmd = command.SetupCommand(cnn, info.ParamReader);
713-
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
714+
reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess));
714715

715716
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache);
716717
cmd = null; // now owned by result
@@ -749,7 +750,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
749750
cmd = command.SetupCommand(cnn, info.ParamReader);
750751

751752
if (wasClosed) cnn.Open();
752-
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
753+
reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
753754
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
754755
// with the CloseConnection flag, so the reader will deal with the connection; we
755756
// still need something in the "finally" to ensure that broken SQL still results
@@ -811,7 +812,7 @@ private static T QueryFirstOrDefaultImpl<T>(this IDbConnection cnn, ref CommandD
811812
cmd = command.SetupCommand(cnn, info.ParamReader);
812813

813814
if (wasClosed) cnn.Open();
814-
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
815+
reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow));
815816
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
816817

817818
T result = default(T);
@@ -1061,7 +1062,7 @@ static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFift
10611062
{
10621063
ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader);
10631064
if (wasClosed) cnn.Open();
1064-
ownedReader = ownedCommand.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
1065+
ownedReader = ownedCommand.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
10651066
reader = ownedReader;
10661067
}
10671068
DeserializerState deserializer = default(DeserializerState);
@@ -1104,7 +1105,10 @@ static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFift
11041105
}
11051106
}
11061107
}
1107-
1108+
private static CommandBehavior GetBehavior(bool close, CommandBehavior @default)
1109+
{
1110+
return close ? (@default | CommandBehavior.CloseConnection) : @default;
1111+
}
11081112
static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn, IDataReader reader, Identity identity, bool finalize)
11091113
{
11101114
if (types.Length < 1)
@@ -1126,7 +1130,7 @@ static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, Comman
11261130
{
11271131
ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader);
11281132
if (wasClosed) cnn.Open();
1129-
ownedReader = ownedCommand.ExecuteReader();
1133+
ownedReader = ownedCommand.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
11301134
reader = ownedReader;
11311135
}
11321136
DeserializerState deserializer = default(DeserializerState);
@@ -2272,8 +2276,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
22722276
{
22732277
cmd = command.SetupCommand(cnn, paramReader);
22742278
if (wasClosed) cnn.Open();
2275-
if (wasClosed) commandBehavior |= CommandBehavior.CloseConnection;
2276-
var reader = cmd.ExecuteReader(commandBehavior);
2279+
var reader = cmd.ExecuteReader(GetBehavior(wasClosed, commandBehavior));
22772280
wasClosed = false; // don't dispose before giving it to them!
22782281
disposeCommand = false;
22792282
// note: command.FireOutputCallbacks(); would be useless here; parameters come at the **end** of the TDS stream

0 commit comments

Comments
 (0)