mirror of
https://github.com/DapperLib/Dapper.git
synced 2026-10-17 05:12:13 +08:00
DynamicParameters.AddParameters(IDbCommand): identity-free self-apply
The full bag protocol (per-parameter DbType/direction/size, templates, literal replacement, RemoveUnused) already lives in AddParameters(command, identity), but the identity requirement makes it uncallable from outside: Identity's constructor is internal, and identity.Sql is consumed on the first line. This overload builds the identity from the command's own text and type, which is what identity.Sql is in practice - letting external tooling (for example build-time code generators, aka Dapper.AOT) apply a bag without reimplementing the protocol. Test covers the bag+literal composition against a closed connection (no database needed).
This commit is contained in:
@@ -147,6 +147,20 @@ namespace Dapper
|
||||
AddParameters(command, identity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add all the parameters needed to the command just before it executes, using the
|
||||
/// command's own text and type for any query-specific handling (literal tokens, etc);
|
||||
/// this allows external tooling (for example build-time code generators) to apply a
|
||||
/// parameter bag without constructing an <see cref="SqlMapper.Identity"/>
|
||||
/// </summary>
|
||||
/// <param name="command">The raw command prior to execution</param>
|
||||
public void AddParameters(IDbCommand command)
|
||||
{
|
||||
if (command is null) throw new ArgumentNullException(nameof(command));
|
||||
AddParameters(command, new SqlMapper.Identity(command.CommandText, command.CommandType,
|
||||
command.Connection!, null, GetType()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, the command-text is inspected and only values that are clearly used are included on the connection
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#nullable enable
|
||||
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.get -> bool
|
||||
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.set -> void
|
||||
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.set -> void
|
||||
Dapper.DynamicParameters.AddParameters(System.Data.IDbCommand! command) -> void
|
||||
|
||||
@@ -928,6 +928,29 @@ namespace Dapper.Tests
|
||||
Assert.Null(p.Get<int?>("@b"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddParameters_Command_AppliesBagAndLiterals()
|
||||
{
|
||||
// the identity-free overload: external tooling (e.g. build-time code generators)
|
||||
// can apply a bag using the command's own text for query-specific handling
|
||||
using var connection = GetClosedConnection();
|
||||
using var command = connection.CreateCommand();
|
||||
command.CommandText = "select @a + {=b}";
|
||||
|
||||
var args = new DynamicParameters();
|
||||
args.Add("a", 1);
|
||||
args.Add("b", 2);
|
||||
args.AddParameters(command);
|
||||
|
||||
Assert.Equal("select @a + 2", command.CommandText); // literal replaced
|
||||
// (note the literal member is still attached as a parameter too - unused, but
|
||||
// that matches what the bag does under vanilla execution)
|
||||
var p = Assert.IsAssignableFrom<IDbDataParameter>(command.Parameters[0]);
|
||||
Assert.Equal("a", p.ParameterName);
|
||||
Assert.Equal(1, p.Value);
|
||||
Assert.Equal(2, command.Parameters.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestAppendingAnonClasses()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user