Моделирование запросов NHibernate - PullRequest
7 голосов
/ 22 октября 2010

Обычно я помещал свои критерии / hql-запросы в класс репозитория / dal, связанный с сущностью, но в последнее время я думал о добавлении еще одной абстракции, которая представляет собой запрос, это дало бы мне возможность добавитьобщее поведение для всех запросов (например, разбиение на страницы) в базовом классе и т. д.

, так что теперь это мои компоненты;

универсальный интерфейс, не связанный с nhibernate:

public interface IQuery<T>
{
    IList<T> List();
    T Single();
}

Пример реализации запроса на основе критериев, нечто подобное можно сделать с помощью запроса Hql или запроса nhibernate-linq

public abstract class CriteriaQuery<T>: IQuery<T>
{
    [Inject]
    public ISessionFactory SessionFactory { protected get; set; }

    protected ISession Session
    {
        get { return SessionFactory.GetCurrentSession(); }
    }

    protected abstract ICriteria Configure(ICriteria criteria);

    [Transaction]
    public virtual IList<T> List()
    {
        var criteria = Session.CreateCriteria(typeof (T));

        return Configure(criteria)
                 .List<T>();
    }

    [Transaction]
    public virtual T Single()
    {
        return Configure(Session.CreateCriteria(typeof(T)))
                .UniqueResult<T>();
    }
}

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

public interface IGetVideosQuery: IQuery<Video>
{
    IGetVideosQuery Page(int index);
    IGetVideosQuery PageSize(int pageSize);

    IGetVideosQuery AllTime { get; }
    IGetVideosQuery Today { get; }
    IGetVideosQuery LastWeek { get; }
}

есть мысли по этому поводу?возможные проблемы, которые вы видите, я мог бы столкнуться?Спасибо!

Ответы [ 2 ]

4 голосов
/ 25 октября 2010

Я выбрал другой путь, CQS . То, что это делает, - то, что это отделяет мою логику мутации от моей логики запроса.

Теперь есть разные идеи о том, как это реализовать, и я выбрал это:

  • Вся моя логика мутаций активируется с помощью таких команд, как DeactivateUser и ChangeRelationAddress. Для этой бизнес-логики у меня есть нормальные репозитории, как вы описываете;

  • Для отображения данных я использую полностью управляемую систему. В этой системе я описываю запросы как Pattern Specification . Я описываю базовую таблицу и поля. Система запросов автоматически создает соединения для меня, и с помощью определений фильтров я предоставляю фильтры.

Эта система позволяет мне снизить сложность моих репозиториев, потому что мне не нужно думать о фильтрах, которые может установить пользователь или ORDER BY. Система, которая отображает эти данные, автоматически создает фильтры с помощью Criteria и обрабатывает пейджинг для меня.

Может быть, такая система может работать на вас.

2 голосов
/ 22 октября 2010

Моим первым предложением было бы использовать Linq2NH, доступный в NHibernate 2.1 и более поздних версиях.Сеанс предоставляет метод AsQueryable<T>(), с помощью которого вы можете построить запрос Linq.Это позволит вам прикреплять критерии и прогнозы по своему усмотрению, используя стандартные методы расширения Linq, в том числе Skip () и Take () для реализации разбиения на страницы (myQuery.Skip(PageIdx*PageSize).Take(PageSize).ToList()) и предложения Where для фильтрации.Лямбды и переменные, используемые в этих запросах, могут быть инкапсулированы в какой-то класс QueryInfo, что позволяет повторять постоянные запросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...