protected virtual IEnumerable <T> ExecuteQuery <T>(string streamId, Func <IDbStatement, IEnumerable <T> > query)
        {
            ThrowWhenDisposed();

            streamId = streamId.ToHash();
            TransactionScope scope       = OpenQueryScope();
            IDbConnection    connection  = null;
            IDbTransaction   transaction = null;
            IDbStatement     statement   = null;

            try
            {
                connection         = _connectionFactory.OpenReplica(streamId);
                transaction        = _dialect.OpenTransaction(connection);
                statement          = _dialect.BuildStatement(scope, connection, transaction);
                statement.PageSize = _pageSize;

                Logger.Verbose(Messages.ExecutingQuery);
                return(query(statement));
            }
            catch (Exception e)
            {
                if (statement != null)
                {
                    statement.Dispose();
                }
                if (transaction != null)
                {
                    transaction.Dispose();
                }
                if (connection != null)
                {
                    connection.Dispose();
                }
                if (scope != null)
                {
                    scope.Dispose();
                }

                Logger.Debug(Messages.StorageThrewException, e.GetType());
                if (e is StorageUnavailableException)
                {
                    throw;
                }

                throw new StorageException(e.Message, e);
            }
        }