/// <summary> /// Create and prepare an IDbCommand, and call ExecuteReader with the appropriate CommandBehavior. /// </summary> /// <remarks> /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed. /// /// If the caller provided the connection, we want to leave it to them to manage. /// </remarks> /// <param name="connection">A valid IDbConnection, on which to execute this command</param> /// <param name="transaction">A valid IDbTransaction, or 'null'</param> /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param> /// <param name="commandText">The stored procedure name or SQL command</param> /// <param name="commandParameters">An array of IDataParameters to be associated with the command or 'null' if no parameters are required</param> /// <param name="connectionOwnership">Indicates whether the connection parameter was provided by the caller, or created by AdoHelper</param> /// <returns>IDataReader containing the results of the command</returns> /// <exception cref="System.InvalidOperationException">Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied</exception> /// <exception cref="System.ArgumentNullException">Thrown if commandText is null</exception> /// <exception cref="System.ArgumentException">Thrown if the parameter count does not match the number of values supplied</exception> /// <exception cref="System.ArgumentNullException">Thrown if connection is null</exception> private IDataReader ExecuteReader(IDbConnection connection, IDbTransaction transaction, CommandType commandType, string commandText, IDataParameter[] commandParameters, AdoConnectionOwnership connectionOwnership) { if( connection == null ) throw new ArgumentNullException( "connection" ); bool mustCloseConnection = false; // Create a command and prepare it for execution IDbCommand cmd = connection.CreateCommand(); try { PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); CleanParameterSyntax(cmd); // override conenctionOwnership if we created the connection in PrepareCommand -- cjbreisch if (mustCloseConnection) { connectionOwnership = AdoConnectionOwnership.Internal; } // Create a reader IDataReader dataReader; dataReader = ExecuteReader(cmd, connectionOwnership); ClearCommand( cmd ); return dataReader; } catch { if( mustCloseConnection ) connection.Close(); throw; } }
/// <summary> /// Execute an IDbCommand (that returns a resultset) against the database specified in /// the connection string. /// </summary> /// <param name="command">The IDbCommand object to use</param> /// <param name="connectionOwnership">Enum indicating whether the connection was created internally or externally.</param> /// <returns>A IDataReader containing the resultset generated by the command</returns> /// <exception cref="System.ArgumentNullException">Thrown if command is null.</exception> protected virtual IDataReader ExecuteReader(IDbCommand command, AdoConnectionOwnership connectionOwnership) { // Clean Up Parameter Syntax CleanParameterSyntax(command); if (command.Connection.State != ConnectionState.Open) { command.Connection.Open(); connectionOwnership = AdoConnectionOwnership.Internal; } // Create a reader IDataReader dataReader; // Call ExecuteReader with the appropriate CommandBehavior if (connectionOwnership == AdoConnectionOwnership.External) { dataReader = command.ExecuteReader(); } else { try { dataReader = command.ExecuteReader(CommandBehavior.CloseConnection); } catch (Exception ex) { // Don't just throw ex. It changes the call stack. But we want the ex around for debugging, so... Debug.WriteLine(ex); throw; } } ClearCommand( command ); return dataReader; }