Add managed connection pooling and execution locking

This commit is contained in:
2026-02-27 17:28:50 +01:00
parent e43d7863ec
commit aedb97e879
12 changed files with 1554 additions and 348 deletions

View File

@@ -159,17 +159,24 @@ namespace DynamORM
/// <summary>Executes an SQL statement against the Connection object of a
/// data provider, and returns the number of rows affected.</summary>
/// <returns>The number of rows affected.</returns>
public int ExecuteNonQuery()
{
try
{
return PrepareForExecution().ExecuteNonQuery();
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
}
public int ExecuteNonQuery()
{
IDisposable scope = null;
try
{
scope = _db != null ? _db.AcquireExecutionScope() : null;
return PrepareForExecution().ExecuteNonQuery();
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
finally
{
if (scope != null)
scope.Dispose();
}
}
/// <summary>Executes the <see cref="P:System.Data.IDbCommand.CommandText"/>
/// against the <see cref="P:System.Data.IDbCommand.Connection"/>,
@@ -178,49 +185,64 @@ namespace DynamORM
/// </summary><param name="behavior">One of the
/// <see cref="T:System.Data.CommandBehavior"/> values.</param>
/// <returns>An <see cref="T:System.Data.IDataReader"/> object.</returns>
public IDataReader ExecuteReader(CommandBehavior behavior)
{
try
{
return PrepareForExecution().ExecuteReader(behavior);
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
}
public IDataReader ExecuteReader(CommandBehavior behavior)
{
IDisposable scope = null;
try
{
scope = _db != null ? _db.AcquireExecutionScope() : null;
return new DynamicExecutionReader(PrepareForExecution().ExecuteReader(behavior), scope);
}
catch (Exception ex)
{
if (scope != null)
scope.Dispose();
throw new DynamicQueryException(ex, this);
}
}
/// <summary>Executes the <see cref="P:System.Data.IDbCommand.CommandText"/>
/// against the <see cref="P:System.Data.IDbCommand.Connection"/> and
/// builds an <see cref="T:System.Data.IDataReader"/>.</summary>
/// <returns>An <see cref="T:System.Data.IDataReader"/> object.</returns>
public IDataReader ExecuteReader()
{
try
{
return PrepareForExecution().ExecuteReader();
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
}
public IDataReader ExecuteReader()
{
IDisposable scope = null;
try
{
scope = _db != null ? _db.AcquireExecutionScope() : null;
return new DynamicExecutionReader(PrepareForExecution().ExecuteReader(), scope);
}
catch (Exception ex)
{
if (scope != null)
scope.Dispose();
throw new DynamicQueryException(ex, this);
}
}
/// <summary>Executes the query, and returns the first column of the
/// first row in the result set returned by the query. Extra columns or
/// rows are ignored.</summary>
/// <returns>The first column of the first row in the result set.</returns>
public object ExecuteScalar()
{
try
{
return PrepareForExecution().ExecuteScalar();
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
}
public object ExecuteScalar()
{
IDisposable scope = null;
try
{
scope = _db != null ? _db.AcquireExecutionScope() : null;
return PrepareForExecution().ExecuteScalar();
}
catch (Exception ex)
{
throw new DynamicQueryException(ex, this);
}
finally
{
if (scope != null)
scope.Dispose();
}
}
/// <summary>Gets the <see cref="T:System.Data.IDataParameterCollection"/>.</summary>
public IDataParameterCollection Parameters
@@ -281,7 +303,7 @@ namespace DynamORM
IsDisposed = true;
if (_con != null)
if (_con != null && db.CommandsPool != null)
{
List<IDbCommand> pool = db.CommandsPool.TryGetValue(_con.Connection);