public void CloseReader(DbDataReader reader)
/* This method was added because PrepareCommand don't really prepare the command
* with its connection.
* In some case we need to manage a reader outsite the command scope.
* To do it we need to use the Batcher.ExecuteReader and then we need something
* to close the opened reader.
// TODO NH: Study a way to use directly DbCommand.ExecuteReader() outsite the batcher
// An example of it's use is the management of generated ID.
if (reader == null)
var rsw = reader as ResultSetWrapper;
var actualReader = rsw == null ? reader : rsw.Target;
var duration = GetReaderStopwatch(actualReader);
catch (Exception e)
// NH2205 - prevent exceptions when closing the reader from hiding any original exception
Log.Warn("exception closing reader", e);
[SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
public virtual DbDataReader ExecuteDataReader(string commandText, CommandType commandType, TimeSpan commandTimeout,
params DbParameter parameters)
throw new ArgumentNullException(nameof(commandText));
DbDataReader results = null;
var open = _explicitlyOpened;
using (var command = PrepCommand(Connection, commandText, commandType, commandTimeout, parameters))
// If the connection was open before execute was called, then do not automatically close connection.
results = open ? command.ExecuteReader() : command.ExecuteReader(CommandBehavior.CloseConnection);
if (results != null && !results.IsClosed)
// ReSharper disable once ExceptionNotDocumented
// ReSharper disable once ThrowingSystemException