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

Rationalize FireOutputCallbacks, and apply to remaining methods

上级 d1e6d6f5
......@@ -52,8 +52,19 @@ public enum CommandFlags
/// <summary>
/// Represents the key aspects of a sql operation
/// </summary>
public struct CommandDefinition
public struct CommandDefinition
{
internal static CommandDefinition ForCallback(object parameters)
{
if(parameters is DynamicParameters)
{
return new CommandDefinition(parameters);
}
else
{
return default(CommandDefinition);
}
}
private readonly string commandText;
private readonly object parameters;
private readonly IDbTransaction transaction;
......@@ -62,7 +73,13 @@ public struct CommandDefinition
private readonly CommandFlags flags;
internal void FireOutputCallbacks()
{
if (parameters is DynamicParameters)
{
((DynamicParameters)parameters).FireOutputCallbacks();
}
}
/// <summary>
/// The command (sql or a stored-procedure name) to execute
/// </summary>
......@@ -130,6 +147,11 @@ public struct CommandDefinition
#endif
}
private CommandDefinition(object parameters) : this()
{
this.parameters = parameters;
}
#if ASYNC
private readonly CancellationToken cancellationToken;
/// <summary>
......@@ -1120,7 +1142,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, objec
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1145,7 +1167,7 @@ public static int Execute(this IDbConnection cnn, CommandDefinition command)
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1161,7 +1183,7 @@ public static int Execute(this IDbConnection cnn, CommandDefinition command)
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1229,6 +1251,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com
total += cmd.ExecuteNonQuery();
}
}
command.FireOutputCallbacks();
} finally
{
if (wasClosed) cnn.Close();
......@@ -1268,7 +1291,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1305,7 +1328,7 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinitio
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
return Query<DapperRow>(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType);
}
......@@ -1362,7 +1385,7 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, bool buffered, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1412,7 +1435,7 @@ public static IEnumerable<T> Query<T>(this IDbConnection cnn, CommandDefinition
#if CSHARP30
this IDbConnection cnn, string sql, object param, IDbTransaction transaction, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1441,7 +1464,7 @@ private static GridReader QueryMultipleImpl(this IDbConnection cnn, ref CommandD
cmd = command.SetupCommand(cnn, info.ParamReader);
reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
var result = new GridReader(cmd, reader, identity);
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters);
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
// still need something in the "finally" to ensure that broken SQL still results
......@@ -1503,10 +1526,13 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
}
}
while (reader.NextResult()) { }
// happy path; close the reader cleanly - no
// need for "Cancel" etc
reader.Dispose();
reader = null;
command.FireOutputCallbacks();
}
finally
{
......@@ -1541,7 +1567,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1569,7 +1595,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1598,7 +1624,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
#endif
)
{
......@@ -1626,7 +1652,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
/// <param name="commandType"></param>
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
)
{
return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, DontMap, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
......@@ -1653,7 +1679,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
/// <param name="commandType"></param>
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>(
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
)
{
return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, DontMap, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
......@@ -1681,7 +1707,7 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
}
......@@ -1734,6 +1760,7 @@ partial class DontMap { }
{
yield return mapIt(reader);
}
command.FireOutputCallbacks();
}
}
finally
......@@ -3022,17 +3049,14 @@ private static int ExecuteCommand(IDbConnection cnn, ref CommandDefinition comma
{
cmd = command.SetupCommand(cnn, paramReader);
if (wasClosed) cnn.Open();
return cmd.ExecuteNonQuery();
int result = cmd.ExecuteNonQuery();
command.FireOutputCallbacks();
return result;
}
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
if (command.Parameters is DynamicParameters)
{
((DynamicParameters)command.Parameters).FireOutputCallbacks();
}
}
}
......@@ -3054,16 +3078,12 @@ private static T ExecuteScalarImpl<T>(IDbConnection cnn, ref CommandDefinition c
cmd = command.SetupCommand(cnn, paramReader);
if (wasClosed) cnn.Open();
result =cmd.ExecuteScalar();
command.FireOutputCallbacks();
}
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
if (command.Parameters is DynamicParameters)
{
((DynamicParameters)command.Parameters).FireOutputCallbacks();
}
}
return Parse<T>(result);
}
......@@ -3081,17 +3101,14 @@ private static IDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefin
if (wasClosed) commandBehavior |= CommandBehavior.CloseConnection;
var reader = cmd.ExecuteReader(commandBehavior);
wasClosed = false; // don't dispose before giving it to them!
// note: command.FireOutputCallbacks(); would be useless here; parameters come at the **end** of the TDS stream
return reader;
}
finally
{
if (wasClosed) cnn.Close();
if (cmd != null) cmd.Dispose();
if (command.Parameters is DynamicParameters)
{
((DynamicParameters)command.Parameters).FireOutputCallbacks();
}
}
}
......@@ -3785,11 +3802,12 @@ public partial class GridReader : IDisposable
private IDbCommand command;
private Identity identity;
internal GridReader(IDbCommand command, IDataReader reader, Identity identity)
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, DynamicParameters dynamicParams)
{
this.command = command;
this.reader = reader;
this.identity = identity;
this.dynamicParams = dynamicParams;
}
#if !CSHARP30
......@@ -3996,6 +4014,8 @@ private IEnumerable<T> ReadDeferred<T>(int index, Func<IDataReader, object> dese
}
private int gridIndex, readCount;
private bool consumed;
private DynamicParameters dynamicParams;
/// <summary>
/// Has the underlying reader been consumed?
/// </summary>
......@@ -4020,7 +4040,7 @@ private void NextResult()
// need for "Cancel" etc
reader.Dispose();
reader = null;
if (dynamicParams != null) dynamicParams.FireOutputCallbacks();
Dispose();
}
}
......
......@@ -95,13 +95,15 @@ private static async Task<IEnumerable<T>> QueryAsync<T>(this IDbConnection cnn,
{
buffer.Add((T)func(reader));
}
while (await reader.NextResultAsync().ConfigureAwait(false)) { }
command.FireOutputCallbacks();
return buffer;
}
else
{
// can't use ReadAsync / cancellation; but this will have to do
wasClosed = false; // don't close if handing back an open reader; rely on the command-behavior
var deferred = ExecuteReaderSync<T>(reader, func);
var deferred = ExecuteReaderSync<T>(reader, func, command.Parameters);
reader = null; // to prevent it being disposed before the caller gets to see it
return deferred;
}
......@@ -211,7 +213,6 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
using (pending.Dequeue().Command) { } // dispose commands
}
}
return total;
}
else
{
......@@ -236,6 +237,8 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
}
}
}
command.FireOutputCallbacks();
}
finally
{
......@@ -253,7 +256,9 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
try
{
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
return await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false);
var result = await cmd.ExecuteNonQueryAsync(command.CancellationToken).ConfigureAwait(false);
command.FireOutputCallbacks();
return result;
}
finally
{
......@@ -446,7 +451,7 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
using (var reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false))
{
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, default(CommandDefinition), map, splitOn, reader, identity);
var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity);
return command.Buffered ? results.ToList() : results;
}
} finally
......@@ -455,12 +460,15 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
}
}
private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDataReader,object> func)
private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDataReader,object> func, object parameters)
{
while (reader.Read())
{
yield return (T)func(reader);
}
while (reader.NextResult()) { }
if (parameters is DynamicParameters)
((DynamicParameters)parameters).FireOutputCallbacks();
}
/// <summary>
......@@ -481,7 +489,7 @@ private static IEnumerable<T> ExecuteReaderSync<T>(IDataReader reader, Func<IDat
partial class GridReader
{
CancellationToken cancel;
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, CancellationToken cancel) : this(command, reader, identity)
internal GridReader(IDbCommand command, IDataReader reader, Identity identity, DynamicParameters dynamicParams, CancellationToken cancel) : this(command, reader, identity, dynamicParams)
{
this.cancel = cancel;
}
......@@ -524,7 +532,7 @@ private async Task NextResultAsync()
// need for "Cancel" etc
reader.Dispose();
reader = null;
if (dynamicParams != null) dynamicParams.FireOutputCallbacks();
Dispose();
}
}
......@@ -600,7 +608,7 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader);
reader = await cmd.ExecuteReaderAsync(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess, command.CancellationToken).ConfigureAwait(false);
var result = new GridReader(cmd, reader, identity, command.CancellationToken);
var result = new GridReader(cmd, reader, identity, command.Parameters as DynamicParameters, command.CancellationToken);
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
// still need something in the "finally" to ensure that broken SQL still results
......@@ -758,6 +766,7 @@ private async static Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
cmd = (DbCommand)command.SetupCommand(cnn, paramReader);
if (wasClosed) await ((DbConnection)cnn).OpenAsync(command.CancellationToken).ConfigureAwait(false);
result = await cmd.ExecuteScalarAsync(command.CancellationToken).ConfigureAwait(false);
command.FireOutputCallbacks();
}
finally
{
......
......@@ -355,5 +355,199 @@ public void Issue22_ExecuteScalar()
k.IsNull();
}
}
public void TestSupportForDynamicParametersOutputExpressions()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
connection.ExecuteAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId", p).Wait();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Scalar()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = (int)connection.ExecuteScalarAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p).Result;
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Default()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Buffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(new CommandDefinition(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, flags: CommandFlags.Buffered)).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_NonBuffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.QueryAsync<int>(new CommandDefinition(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, flags: CommandFlags.None)).Result.Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_QueryMultiple()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
int x, y;
using(var multi = connection.QueryMultipleAsync(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
select 42
select 17
SET @AddressPersonId = @PersonId", p).Result)
{
x = multi.ReadAsync<int>().Result.Single();
y = multi.ReadAsync<int>().Result.Single();
}
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
x.IsEqualTo(42);
y.IsEqualTo(17);
}
}
class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string Occupation { get; private set; }
public int NumberOfLegs = 2;
public Address Address { get; set; }
}
class Address
{
public int AddressId { get; set; }
public string Name { get; set; }
public int PersonId { get; set; }
}
}
}
\ No newline at end of file
......@@ -1201,7 +1201,130 @@ public void TestSupportForDynamicParametersOutputExpressions()
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
}
public void TestSupportForDynamicParametersOutputExpressions_Scalar()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = (int)connection.ExecuteScalar(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p);
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_Buffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: true).Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_Query_NonBuffered()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
var result = connection.Query<int>(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
SET @AddressPersonId = @PersonId
select 42", p, buffered: false).Single();
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
result.IsEqualTo(42);
}
}
public void TestSupportForDynamicParametersOutputExpressions_QueryMultiple()
{
using (var connection = Program.GetOpenConnection())
{
var bob = new Person { Name = "bob", PersonId = 1, Address = new Address { PersonId = 2 } };
var p = new DynamicParameters(bob);
p.Output(bob, b => b.PersonId);
p.Output(bob, b => b.Occupation);
p.Output(bob, b => b.NumberOfLegs);
p.Output(bob, b => b.Address.Name);
p.Output(bob, b => b.Address.PersonId);
int x, y;
using (var multi = connection.QueryMultiple(@"
SET @Occupation = 'grillmaster'
SET @PersonId = @PersonId + 1
SET @NumberOfLegs = @NumberOfLegs - 1
SET @AddressName = 'bobs burgers'
select 42
select 17
SET @AddressPersonId = @PersonId", p))
{
x = multi.Read<int>().Single();
y = multi.Read<int>().Single();
}
bob.Occupation.IsEqualTo("grillmaster");
bob.PersonId.IsEqualTo(2);
bob.NumberOfLegs.IsEqualTo(1);
bob.Address.Name.IsEqualTo("bobs burgers");
bob.Address.PersonId.IsEqualTo(2);
x.IsEqualTo(42);
y.IsEqualTo(17);
}
}
public void TestSupportForExpandoObjectParameters()
{
dynamic p = new ExpandoObject();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册