public override IDataReader ExecuteReader(string commandText, params DbParam [] parameters)
        {
            MySqlConnection        conn    = null;
            MySqlCommand           command = null;
            MySQLDataReaderWrapper dr      = null;
            DateTime start      = DateTime.Now;
            bool     isReadOnly = false;

            try {
                command = GetCommand(out conn, commandText, parameters, out isReadOnly);
                if (command == null)
                {
                    return(null);
                }

                //create a reader and use a stupid retry as sometimes the server kills the query for no good reason
                IDataReader reader = command.ExecuteReader() ?? command.ExecuteReader() ?? command.ExecuteReader();
                if (reader == null)
                {
                    throw new DbConnectionLostException("Could not get a valid reader from the database");
                }

                dr           = new MySQLDataReaderWrapper(conn, TransactionContext.Current, reader, command);
                dr.Disposed += DataReader_Disposed;

                // detach the SqlParameters from the command object, so they can be used again.
                command.Parameters.Clear();
            } catch (MySqlException ex) {
                CleanupReaderOnError(dr, conn, command);
                if (ex.HasException <SocketException> () ||
                    ex.HasException <TargetInvocationException> () ||
                    ex.HasException <TimeoutException> ())
                {
                    throw new DbConnectionLostException(ex);
                }

                throw new Exception("MySql", ex);
            } catch (DbConnectionLostException) {
                CleanupReaderOnError(dr, conn, command);
                throw;
            } catch {
                CleanupReaderOnError(dr, conn, command);
            } finally {
                OnCommandExecuted(commandText, start, parameters, isReadOnly);
            }

            return(dr);
        }
        private void CleanupReaderOnError(MySQLDataReaderWrapper dr, MySqlConnection conn, MySqlCommand command)
        {
            TransactionContext context = TransactionContext.Current;

            if (dr != null && !dr.IsDisposed)
            {
                DataReader_Disposed(dr, new DataReaderDisposedEventArgs(conn, context, command));
                return;
            }

            if (command != null && context != null)
            {
                context.ReleaseConnection();
            }

            if (command != null)
            {
                command.Dispose();
            }
        }