I have a method like below code. I pass a SqlConnection
and a Transaction
to the nested methods.
public async Task<IdentityResult> M(Model model, CancellationToken cancellationToken,
SqlTransaction transaction = null)
{
IdentityResult result;
using (transaction = _sqlConnection.BeginTransaction())
{
try
{
result = await M1(_sqlConnection,model, cancellationToken, transaction);
if (result.Succeeded)
{
result = await M2(_sqlConnection,model,cancellationToken, transaction);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
result = GeneralErrors.Failed;
}
}
return result;
}
When compiler comes to here:
internal async Task<IdentityResult> M1(SqlConnection connection,Model model,CancellationToken cancellationToken, SqlTransaction transaction = null)
{
using (var multi = connection.QueryMultiple(query.Query,transaction)) // Error
{
//...
}
}
I get this error when I call QueryMultiple
method of Dapper.net:
System.InvalidOperationException: 'ExecuteReader requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.'
How can I find out where is the problem?
When you call
connection.QueryMultiple(query.Query,transaction)
you actually use following overload of QueryMultiple
extension method:
GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);
As you see, second transaction
parameter that you pass to QueryMultiple
call is not considered as transaction object, but as param
for the query.
To fix this, either name transaction
param explicitly:
using (var multi = connection.QueryMultiple(query.Query, transaction: transaction))
or explicitly pass null
value for param
argument:
using (var multi = connection.QueryMultiple(query.Query, null, transaction))