diff --git a/Dapper NET40/SqlMapper.cs b/Dapper NET40/SqlMapper.cs
index 3571aa9d0ded20a180219581888691b2fe36e037..7d2f38f962c822e9623d7c4eadff07765e2167cf 100644
--- a/Dapper NET40/SqlMapper.cs
+++ b/Dapper NET40/SqlMapper.cs
@@ -52,8 +52,19 @@ public enum CommandFlags
///
/// Represents the key aspects of a sql operation
///
- 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();
+ }
+ }
///
/// The command (sql or a stored-procedure name) to execute
///
@@ -130,6 +147,11 @@ public struct CommandDefinition
#endif
}
+ private CommandDefinition(object parameters) : this()
+ {
+ this.parameters = parameters;
+ }
+
#if ASYNC
private readonly CancellationToken cancellationToken;
///
@@ -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
///
/// Return a list of dynamic objects, reader is closed after the call
///
- public static IEnumerable Query(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
+ public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
return Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType);
}
@@ -1362,7 +1385,7 @@ public static IEnumerable 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 Query(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 QueryImpl(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 QueryImpl(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
-this IDbConnection cnn, string sql, Func 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 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 QueryImpl(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
-this IDbConnection cnn, string sql, Func 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 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 QueryImpl(this IDbConnection cnn, CommandDefini
#if CSHARP30
this IDbConnection cnn, string sql, Func map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType
#else
-this IDbConnection cnn, string sql, Func 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 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 QueryImpl(this IDbConnection cnn, CommandDefini
///
///
public static IEnumerable Query(
- this IDbConnection cnn, string sql, Func 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 map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
)
{
return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
@@ -1653,7 +1679,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini
///
///
public static IEnumerable Query(
- this IDbConnection cnn, string sql, Func 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 map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null
)
{
return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
@@ -1681,7 +1707,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini
///
///
///
- public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
+ public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
{
return MultiMap(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(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(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 ReadDeferred(int index, Func dese
}
private int gridIndex, readCount;
private bool consumed;
+ private DynamicParameters dynamicParams;
+
///
/// Has the underlying reader been consumed?
///
@@ -4020,7 +4040,7 @@ private void NextResult()
// need for "Cancel" etc
reader.Dispose();
reader = null;
-
+ if (dynamicParams != null) dynamicParams.FireOutputCallbacks();
Dispose();
}
}
diff --git a/Dapper NET45/SqlMapperAsync.cs b/Dapper NET45/SqlMapperAsync.cs
index 588583692e2b63ece9010e5cb010cbbfcadf810f..b2d672f68c53c62c69864734f5188aa69b8c73a0 100644
--- a/Dapper NET45/SqlMapperAsync.cs
+++ b/Dapper NET45/SqlMapperAsync.cs
@@ -95,13 +95,15 @@ private static async Task> QueryAsync(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(reader, func);
+ var deferred = ExecuteReaderSync(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 ExecuteMultiImplAsync(IDbConnection cnn, CommandD
using (pending.Dequeue().Command) { } // dispose commands
}
}
- return total;
}
else
{
@@ -236,6 +237,8 @@ private static async Task ExecuteMultiImplAsync(IDbConnection cnn, CommandD
}
}
}
+
+ command.FireOutputCallbacks();
}
finally
{
@@ -253,7 +256,9 @@ private static async Task 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 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(null, default(CommandDefinition), map, splitOn, reader, identity);
+ var results = MultiMapImpl(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity);
return command.Buffered ? results.ToList() : results;
}
} finally
@@ -455,12 +460,15 @@ private static async Task ExecuteImplAsync(IDbConnection cnn, CommandDefini
}
}
- private static IEnumerable ExecuteReaderSync(IDataReader reader, Func func)
+ private static IEnumerable ExecuteReaderSync(IDataReader reader, Func func, object parameters)
{
while (reader.Read())
{
yield return (T)func(reader);
}
+ while (reader.NextResult()) { }
+ if (parameters is DynamicParameters)
+ ((DynamicParameters)parameters).FireOutputCallbacks();
}
///
@@ -481,7 +489,7 @@ private static IEnumerable ExecuteReaderSync(IDataReader reader, Func 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 ExecuteScalarImplAsync(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
{
diff --git a/DapperTests NET45/Tests.cs b/DapperTests NET45/Tests.cs
index a6604bc499fe2212c6c3726c5b2ec5871b18d86e..2abcb0699f50b7a75bfab4beffe24d20e731fd01 100644
--- a/DapperTests NET45/Tests.cs
+++ b/DapperTests NET45/Tests.cs
@@ -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(@"
+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(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(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().Result.Single();
+ y = multi.ReadAsync().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
diff --git a/Tests/Tests.cs b/Tests/Tests.cs
index 489762a55c1045fb368f7963c02861becc3108fa..c4b44d5b661cfd001e1e5f7d9ff9dcf62d1f71a0 100644
--- a/Tests/Tests.cs
+++ b/Tests/Tests.cs
@@ -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(@"
+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(@"
+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().Single();
+ y = multi.Read().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();