From e0a1bccd52e330411e07e72b5cd6c131d31154cc Mon Sep 17 00:00:00 2001 From: "Kasper B. Graversen" Date: Mon, 5 Feb 2024 21:45:18 +0100 Subject: [PATCH] Exposing the transaction used in class Database. This enables to do queries not supported by rainbow within the same transaction Closes #1944 --- Dapper.Rainbow/Database.Async.cs | 8 ++++---- Dapper.Rainbow/Database.cs | 32 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Dapper.Rainbow/Database.Async.cs b/Dapper.Rainbow/Database.Async.cs index cdbf7e41f..e1a78c47b 100644 --- a/Dapper.Rainbow/Database.Async.cs +++ b/Dapper.Rainbow/Database.Async.cs @@ -88,7 +88,7 @@ public Task> AllAsync() => /// The parameters to use. /// The number of rows affected. public Task ExecuteAsync(string sql, dynamic param = null) => - _connection.ExecuteAsync(sql, param as object, _transaction, _commandTimeout); + _connection.ExecuteAsync(sql, param as object, Transaction, _commandTimeout); /// /// Asynchronously queries the current database. @@ -98,7 +98,7 @@ public Task ExecuteAsync(string sql, dynamic param = null) => /// The parameters to use. /// An enumerable of for the rows fetched. public Task> QueryAsync(string sql, dynamic param = null) => - _connection.QueryAsync(sql, param as object, _transaction, _commandTimeout); + _connection.QueryAsync(sql, param as object, Transaction, _commandTimeout); /// /// Asynchronously queries the current database for a single record. @@ -108,7 +108,7 @@ public Task> QueryAsync(string sql, dynamic param = null) => /// The parameters to use. /// An enumerable of for the rows fetched. public Task QueryFirstOrDefaultAsync(string sql, dynamic param = null) => - _connection.QueryFirstOrDefaultAsync(sql, param as object, _transaction, _commandTimeout); + _connection.QueryFirstOrDefaultAsync(sql, param as object, Transaction, _commandTimeout); /// /// Perform an asynchronous multi-mapping query with 2 input types. @@ -195,7 +195,7 @@ public Task> QueryAsyncThe parameters to use. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> public Task> QueryAsync(string sql, dynamic param = null) => - _connection.QueryAsync(sql, param as object, _transaction); + _connection.QueryAsync(sql, param as object, Transaction); /// /// Execute a command that returns multiple result sets, and access each in turn. diff --git a/Dapper.Rainbow/Database.cs b/Dapper.Rainbow/Database.cs index 670f22631..58d7298b1 100644 --- a/Dapper.Rainbow/Database.cs +++ b/Dapper.Rainbow/Database.cs @@ -175,7 +175,11 @@ public Table(Database database, string likelyTableName) private DbConnection _connection; private int _commandTimeout; - private DbTransaction _transaction; + + /// + /// Get access to the underlying transaction + /// + public DbTransaction Transaction { get; } /// /// Get underlying database connection. @@ -215,9 +219,11 @@ internal virtual Action CreateTableConstructorForTable() /// Begins a transaction in this database. /// /// The isolation level to use. - public void BeginTransaction(IsolationLevel isolation = IsolationLevel.ReadCommitted) + /// The transaction created + public DbTransaction BeginTransaction(IsolationLevel isolation = IsolationLevel.ReadCommitted) { - _transaction = _connection.BeginTransaction(isolation); + Transaction = _connection.BeginTransaction(isolation); + return Transaction; } /// @@ -225,8 +231,8 @@ public void BeginTransaction(IsolationLevel isolation = IsolationLevel.ReadCommi /// public void CommitTransaction() { - _transaction.Commit(); - _transaction = null; + Transaction.Commit(); + Transaction = null; } /// @@ -234,8 +240,8 @@ public void CommitTransaction() /// public void RollbackTransaction() { - _transaction.Rollback(); - _transaction = null; + Transaction.Rollback(); + Transaction = null; } /// @@ -336,7 +342,7 @@ private bool TableExists(string name) if (!string.IsNullOrEmpty(schemaName)) builder.Append("TABLE_SCHEMA = @schemaName AND "); builder.Append("TABLE_NAME = @name"); - return _connection.Query(builder.ToString(), new { schemaName, name }, _transaction).Count() == 1; + return _connection.Query(builder.ToString(), new { schemaName, name }, Transaction).Count() == 1; } /// @@ -346,7 +352,7 @@ private bool TableExists(string name) /// The parameters to use. /// The number of rows affected. public int Execute(string sql, dynamic param = null) => - _connection.Execute(sql, param as object, _transaction, _commandTimeout); + _connection.Execute(sql, param as object, Transaction, _commandTimeout); /// /// Queries the current database. @@ -357,7 +363,7 @@ public int Execute(string sql, dynamic param = null) => /// Whether to buffer the results. /// An enumerable of for the rows fetched. public IEnumerable Query(string sql, dynamic param = null, bool buffered = true) => - _connection.Query(sql, param as object, _transaction, buffered, _commandTimeout); + _connection.Query(sql, param as object, Transaction, buffered, _commandTimeout); /// /// Queries the current database for a single record. @@ -367,7 +373,7 @@ public IEnumerable Query(string sql, dynamic param = null, bool buffered = /// The parameters to use. /// An enumerable of for the rows fetched. public T QueryFirstOrDefault(string sql, dynamic param = null) => - _connection.QueryFirstOrDefault(sql, param as object, _transaction, _commandTimeout); + _connection.QueryFirstOrDefault(sql, param as object, Transaction, _commandTimeout); /// /// Perform a multi-mapping query with 2 input types. @@ -455,7 +461,7 @@ public IEnumerable QueryWhether the results should be buffered in memory. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> public IEnumerable Query(string sql, dynamic param = null, bool buffered = true) => - _connection.Query(sql, param as object, _transaction, buffered); + _connection.Query(sql, param as object, Transaction, buffered); /// /// Execute a command that returns multiple result sets, and access each in turn. @@ -477,7 +483,7 @@ public virtual void Dispose() if (connection.State != ConnectionState.Closed) { _connection = null; - _transaction = null; + Transaction = null; connection?.Close(); } GC.SuppressFinalize(this);