Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom CreateCommand method. Resolves #2127 #2128

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
}