Commit ec3a1953 authored by Marc Gravell's avatar Marc Gravell

Use single-row/single-result hint when possible

parent 65b26d6e
...@@ -4,9 +4,9 @@ namespace Dapper.Tests ...@@ -4,9 +4,9 @@ namespace Dapper.Tests
{ {
public static class Assert public static class Assert
{ {
public static void IsEqualTo<T>(this T obj, T other) public static void IsEqualTo<T>(this T expected, T actual)
{ {
Xunit.Assert.Equal(obj, other); Xunit.Assert.Equal(expected, actual);
} }
public static void IsSequenceEqualTo<T>(this IEnumerable<T> obj, IEnumerable<T> other) public static void IsSequenceEqualTo<T>(this IEnumerable<T> obj, IEnumerable<T> other)
......
...@@ -117,7 +117,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn, ...@@ -117,7 +117,7 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
try try
{ {
if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, cancel).ConfigureAwait(false); reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), cancel).ConfigureAwait(false);
var tuple = info.Deserializer; var tuple = info.Deserializer;
int hash = GetColumnHash(reader); int hash = GetColumnHash(reader);
...@@ -179,7 +179,7 @@ private static async Task<T> QueryFirstOrDefaultAsync<T>(this IDbConnection cnn, ...@@ -179,7 +179,7 @@ private static async Task<T> QueryFirstOrDefaultAsync<T>(this IDbConnection cnn,
try try
{ {
if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync(cancel).ConfigureAwait(false);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, cancel).ConfigureAwait(false); reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow), cancel).ConfigureAwait(false);
T result = default(T); T result = default(T);
if(await reader.ReadAsync(cancel).ConfigureAwait(false)) if(await reader.ReadAsync(cancel).ConfigureAwait(false))
...@@ -547,7 +547,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini ...@@ -547,7 +547,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
{ {
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
using (var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false)) using (var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), command.CancellationToken).ConfigureAwait(false))
{ {
if (!command.Buffered) wasClosed = false; // handing back open reader; rely on command-behavior if (!command.Buffered) wasClosed = false; // handing back open reader; rely on command-behavior
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity, true); 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 ...@@ -594,7 +594,7 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbC
try { try {
if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false);
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
using (var reader = await cmd.ExecuteReaderAsync(command.CancellationToken).ConfigureAwait(false)) { using (var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult), command.CancellationToken).ConfigureAwait(false)) {
var results = MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, true); var results = MultiMapImpl<TReturn>(null, default(CommandDefinition), types, map, splitOn, reader, identity, true);
return command.Buffered ? results.ToList() : results; return command.Buffered ? results.ToList() : results;
} }
...@@ -644,7 +644,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn, ...@@ -644,7 +644,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
{ {
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader); cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false); reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess), command.CancellationToken).ConfigureAwait(false);
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache, command.CancellationToken); var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache, command.CancellationToken);
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader 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, ...@@ -721,7 +721,7 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn,
{ {
cmd = (DbCommand)command.SetupCommand(cnn, paramReader); cmd = (DbCommand)command.SetupCommand(cnn, paramReader);
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false); if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false); var reader = await cmd.ExecuteReaderAsync(GetBehavior(wasClosed, CommandBehavior.SequentialAccess), command.CancellationToken).ConfigureAwait(false);
wasClosed = false; wasClosed = false;
return reader; return reader;
} }
......
...@@ -697,6 +697,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition ...@@ -697,6 +697,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition
{ {
return QueryMultipleImpl(cnn, ref command); return QueryMultipleImpl(cnn, ref command);
} }
private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandDefinition command) private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandDefinition command)
{ {
object param = command.Parameters; object param = command.Parameters;
...@@ -710,7 +711,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD ...@@ -710,7 +711,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
{ {
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
cmd = command.SetupCommand(cnn, info.ParamReader); cmd = command.SetupCommand(cnn, info.ParamReader);
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess));
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache); var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.AddToCache);
cmd = null; // now owned by result cmd = null; // now owned by result
...@@ -749,7 +750,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini ...@@ -749,7 +750,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
cmd = command.SetupCommand(cnn, info.ParamReader); cmd = command.SetupCommand(cnn, info.ParamReader);
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
// with the CloseConnection flag, so the reader will deal with the connection; we // with the CloseConnection flag, so the reader will deal with the connection; we
// still need something in the "finally" to ensure that broken SQL still results // 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 ...@@ -811,7 +812,7 @@ private static T QueryFirstOrDefaultImpl<T>(this IDbConnection cnn, ref CommandD
cmd = command.SetupCommand(cnn, info.ParamReader); cmd = command.SetupCommand(cnn, info.ParamReader);
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); reader = cmd.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow));
wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader wasClosed = false; // *if* the connection was closed and we got this far, then we now have a reader
T result = default(T); T result = default(T);
...@@ -1061,7 +1062,7 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string ...@@ -1061,7 +1062,7 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string
{ {
ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader); ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader);
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
ownedReader = ownedCommand.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess); ownedReader = ownedCommand.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
reader = ownedReader; reader = ownedReader;
} }
DeserializerState deserializer = default(DeserializerState); DeserializerState deserializer = default(DeserializerState);
...@@ -1104,7 +1105,10 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string ...@@ -1104,7 +1105,10 @@ public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string
} }
} }
} }
private static CommandBehavior GetBehavior(bool close, CommandBehavior @default)
{
return close ? (@default | CommandBehavior.CloseConnection) : @default;
}
static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn, IDataReader reader, Identity identity, bool finalize) static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn, IDataReader reader, Identity identity, bool finalize)
{ {
if (types.Length < 1) if (types.Length < 1)
...@@ -1126,7 +1130,7 @@ static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, Comman ...@@ -1126,7 +1130,7 @@ static IEnumerable<TReturn> MultiMapImpl<TReturn>(this IDbConnection cnn, Comman
{ {
ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader); ownedCommand = command.SetupCommand(cnn, cinfo.ParamReader);
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
ownedReader = ownedCommand.ExecuteReader(); ownedReader = ownedCommand.ExecuteReader(GetBehavior(wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult));
reader = ownedReader; reader = ownedReader;
} }
DeserializerState deserializer = default(DeserializerState); DeserializerState deserializer = default(DeserializerState);
...@@ -2272,8 +2276,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin ...@@ -2272,8 +2276,7 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
{ {
cmd = command.SetupCommand(cnn, paramReader); cmd = command.SetupCommand(cnn, paramReader);
if (wasClosed) cnn.Open(); if (wasClosed) cnn.Open();
if (wasClosed) commandBehavior |= CommandBehavior.CloseConnection; var reader = cmd.ExecuteReader(GetBehavior(wasClosed, commandBehavior));
var reader = cmd.ExecuteReader(commandBehavior);
wasClosed = false; // don't dispose before giving it to them! wasClosed = false; // don't dispose before giving it to them!
disposeCommand = false; disposeCommand = false;
// note: command.FireOutputCallbacks(); would be useless here; parameters come at the **end** of the TDS stream // note: command.FireOutputCallbacks(); would be useless here; parameters come at the **end** of the TDS stream
......
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