Могу ли я (и должен ли) принудительно выполнять будущие запросы NHibernate в определенный момент?

Я использую будущие запросы NHibernate в веб-приложении MVC 3 и пытаюсь сохранить весь доступ к моей базе данных в моих контроллерах, а не в моих представлениях. каталог ресурсов (описательные аннотации), которые содержат коллекцию оценок "многие ко многим" и коллекцию тем "многие ко многим". Пользователи выбирают одну или несколько оценок и одну или несколько тем, а затем получают список подходящих ресурсов.

Чтобы заполнить форму поиска, я использую будущие запросы для получения всех оценок и тем:

    public Domain.SearchFormData GetSearchFormData()
    {
        // Get all grades and all topics using a multiquery.

        IEnumerable<Grade> grades = Session.QueryOver<Grade>()
            .Future();

        IEnumerable<Topic> topics = Session.QueryOver<Topic>()
            .Future();

        var result = new SearchFormData();
        result.Grades = grades;
        result.Topics = topics;
        return result;
    }

Это очень просто, отлично работает и возвращает SearchFormData , который является простым DTO. Этот запрос выполняется в контроллере, и результат не требует дальнейшей обработки, поэтому он передается прямо в представление для визуализации в виде списков флажков.

Но из-за ленивого выполнения при будущих запросах доступ к базе данных не запускается, пока представление не начнет итерацию списков. Это считается некоторыми ( как NHibernate Profiler), и они говорят, что к тому времени, когда представление начнет рендеринг, весь доступ к базе данных должен быть выполнен. Основная причина в том, что в противном случае легко иметь скрытый SELECT N + 1.

Здесь это не применимо; и оценка, и тема - простые объекты без коллекций. Я не особо возражаю, что представление вызовет доступ к базе данных. Но это заставляет меня искать чистый, ясный способ инициировать все будущие запросы. Один из способов сделать это - получить доступ к результатам, например скопировав IEnumerable в список. Но это не совсем то, что мне нужно делать; Я просто хочу выполнить поставленные в очередь запросы.

Я думаю, что триггер имеет смысл срабатывать вне указанного выше запроса. Мне могут понадобиться другие данные для рендеринга полного просмотра страницы, и я могу использовать другие будущие запросы для их получения. Например, на домашней странице также могут отображаться пять самых популярных ресурсов и общее количество ресурсов. Тогда контроллер будет вызывать несколько методов для накопления того, что ему нужно для представления, и было бы наиболее эффективно выполнять их все сразу. Конечно, один из способов сделать это - расширить мои GetSearchFormData до GetAllHomePageData и вернуть DTO с полями для всего на домашней странице. Но я использую форму поиска повсюду, а не только на домашней странице. Таким образом, я бы потерял некоторую красивую модульность.

5
задан Carl Raymond 13 June 2011 в 16:55
поделиться