Obteniendo System.InvalidOperationException en el método anidado evan después de llamar a BeginTransaction

asp.net-core-1.1 c# dapper sql-server

Pregunta

Tengo un método como el siguiente código. Paso una SqlConnection y una Transaction a los métodos anidados.

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;
}

Cuando el compilador viene aquí:

 internal async Task<IdentityResult> M1(SqlConnection connection,Model model,CancellationToken cancellationToken,  SqlTransaction transaction = null)
 {
     using (var multi = connection.QueryMultiple(query.Query,transaction)) // Error
     {
          //...
     }
  }

Me sale este error cuando llamo QueryMultiple método QueryMultiple de Dapper.net:

System.InvalidOperationException: 'ExecuteReader requiere que el comando tenga una transacción cuando la conexión asignada al comando se encuentra en una transacción local pendiente. La propiedad de Transacción del comando no se ha inicializado. '

¿Cómo puedo averiguar dónde está el problema?

Respuesta popular

Cuando usted llama

connection.QueryMultiple(query.Query,transaction)

en realidad usas la siguiente sobrecarga del método de extensión QueryMultiple :

GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null);

Como puede ver, el segundo parámetro de transaction que pasa a la llamada QueryMultiple no se considera como objeto de transacción, sino como param para la consulta.

Para solucionar esto, nombre el parámetro de transaction explícitamente:

using (var multi = connection.QueryMultiple(query.Query, transaction: transaction))

o pase explícitamente el valor null para el argumento param :

using (var multi = connection.QueryMultiple(query.Query, null, transaction))


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué