Skip to content

Commit

Permalink
Custom CreateCommand method. Resolves #2127
Browse files Browse the repository at this point in the history
This allows the user to provide their own IDbCommand to be used by Dapper internally.
  • Loading branch information
billrob committed Oct 31, 2024
1 parent 00a3808 commit c6c8180
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
32 changes: 31 additions & 1 deletion Dapper/CommandDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ internal void OnCompleted()
/// </summary>
public CommandFlags Flags { get; }

/// <summary>
/// The create Func that will be used to create the IDbCommand. When null the connection.CreateCommand() will be used.
/// </summary>
internal Func<IDbConnection, IDbCommand>? CreateCommand { get; }

/// <summary>
/// Can async queries be pipelined?
/// </summary>
Expand Down Expand Up @@ -95,6 +100,26 @@ public CommandDefinition(string commandText, object? parameters = null, IDbTrans
CancellationToken = cancellationToken;
}

/// <summary>
/// Initialize the command definition
/// </summary>
/// <param name="commandText">The text for this command.</param>
/// <param name="createCommand">The a custom way to create a IDbCommand object. This is to override the default connection.CreateCommand() behavior.</param>
/// <param name="parameters">The parameters for this command.</param>
/// <param name="transaction">The transaction for this command to participate in.</param>
/// <param name="commandTimeout">The timeout (in seconds) for this command.</param>
/// <param name="commandType">The <see cref="CommandType"/> for this command.</param>
/// <param name="flags">The behavior flags for this command.</param>
/// <param name="cancellationToken">The cancellation token for this command.</param>
public CommandDefinition(string commandText, Func<IDbConnection, IDbCommand> createCommand, object? parameters = null, IDbTransaction? transaction = null,
int? commandTimeout = null, CommandType? commandType = null, CommandFlags flags = CommandFlags.Buffered
, CancellationToken cancellationToken = default
)
: this(commandText, parameters, transaction, commandTimeout, commandType, flags, cancellationToken)
{
CreateCommand = createCommand;
}

internal static CommandType InferCommandType(string sql)
{
// if the sql contains any whitespace character (space/tab/cr/lf/etc - via unicode),
Expand All @@ -120,7 +145,12 @@ private CommandDefinition(object? parameters, CommandFlags flags) : this()

internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object?>? paramReader)
{
var cmd = cnn.CreateCommand();
IDbCommand cmd;
if (CreateCommand == null)
cmd = cnn.CreateCommand();
else
cmd = CreateCommand(cnn);

var init = GetInit(cmd.GetType());
init?.Invoke(cmd);
if (Transaction is not null)
Expand Down
1 change: 1 addition & 0 deletions Dapper/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Dapper.CommandDefinition.Buffered.get -> bool
Dapper.CommandDefinition.CancellationToken.get -> System.Threading.CancellationToken
Dapper.CommandDefinition.CommandDefinition() -> void
Dapper.CommandDefinition.CommandDefinition(string! commandText, object? parameters = null, System.Data.IDbTransaction? transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null, Dapper.CommandFlags flags = Dapper.CommandFlags.Buffered, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> void
Dapper.CommandDefinition.CommandDefinition(string! commandText, System.Func<System.Data.IDbConnection!, System.Data.IDbCommand!>! createCommand, object? parameters = null, System.Data.IDbTransaction? transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null, Dapper.CommandFlags flags = Dapper.CommandFlags.Buffered, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> void
Dapper.CommandDefinition.CommandText.get -> string!
Dapper.CommandDefinition.CommandTimeout.get -> int?
Dapper.CommandDefinition.CommandType.get -> System.Data.CommandType?
Expand Down
17 changes: 17 additions & 0 deletions tests/Dapper.Tests/MiscTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1394,5 +1394,22 @@ public void SetDynamicProperty_WithValueType_Succeeds()
obj.NewProperty = true;
Assert.True(obj.NewProperty);
}

[Fact]
public void TestCreateCommandCalled()
{
var customCreateCommandCalled = false;
var createCommand = new Func<IDbConnection, IDbCommand>(conn =>
{
customCreateCommandCalled = true;
return conn.CreateCommand();
});

var definition = new CommandDefinition("select 1", createCommand);

connection.Query<int>(definition);

Assert.True(customCreateCommandCalled);
}
}
}

0 comments on commit c6c8180

Please sign in to comment.