Шаблон репозитория с NHibernate? - PullRequest
5 голосов
/ 02 января 2012

Мне интересно, сколько мой сервисный уровень должен знать о моем хранилище? В прошлом проекте я всегда возвращал списки и имел метод для каждой вещи, в которой я нуждался.

Так что если бы мне нужно было вернуть все строки с идентификатором 5, это был бы метод. У меня есть общий репозиторий для создания, обновления, удаления и других опций NHibernate, но для запросов у меня нет.

Теперь я начинаю использовать больше IQueryable, так как столкнулся с проблемами, связанными с наличием большого количества методов для каждого случая.

Скажем, если мне нужно вернуть все, которые имеют определенный Id и нуждаются в 3 таблицах, то, где загружено с нетерпением, это будет новый метод. Если бы мне нужен был определенный Id, а не быстрая загрузка, это был бы отдельный метод.

Так что теперь я думаю, что если я использую метод, который выполняет часть условия where и возвращает IQueryable, тогда я могу добавить результат (т. Е. Если мне нужно будет загружаться).

В то же время, хотя теперь это делает уровень обслуживания более осведомленным о уровне хранилища, и я больше не могу переключать хранилище так же просто, как теперь у меня есть определенный NHibernate на уровне обслуживания.

Я также не уверен, как это повлияет на насмешку.

Так что теперь мне интересно, пойду ли я по этому маршруту, нужен ли репозиторий, как сейчас кажется, что они были смешаны вместе.

Редактировать

Если я избавляюсь от своего репозитория и просто имею сеанс в своем сервисном слое, есть ли смысл иметь единицу рабочего класса тогда?

public class UnitOfWork : IUnitOfWork, IDisposable
    {
        private ITransaction transaction;
        private readonly ISession session;

        public UnitOfWork(ISession session)
        {
            this.session = session;
            session.FlushMode = FlushMode.Auto;
        }

        /// <summary>
        /// Starts a transaction with the database. Uses IsolationLevel.ReadCommitted
        /// </summary>
        public void BeginTransaction()
        {
            transaction = session.BeginTransaction(IsolationLevel.ReadCommitted);
        }

        /// <summary>
        /// starts a transaction with the database.
        /// </summary>
        /// <param name="level">IsolationLevel the transaction should run in.</param>
        public void BeginTransaction(IsolationLevel level)
        {
            transaction = session.BeginTransaction(level);
        }

        private bool IsTransactionActive()
        {
            return transaction.IsActive;
        }

        /// <summary>
        /// Commits the transaction and writes to the database.
        /// </summary>
        public void Commit()
        {
            // make sure a transaction was started before we try to commit.
            if (!IsTransactionActive())
            {
                throw new InvalidOperationException("Oops! We don't have an active transaction. Did a rollback occur before this commit was triggered: "
                                                            + transaction.WasRolledBack + " did a commit happen before this commit: " + transaction.WasCommitted);
            }

            transaction.Commit();
        }

        /// <summary>
        /// Rollback any writes to the databases.
        /// </summary>
        public void Rollback()
        {
            if (IsTransactionActive())
            {
                transaction.Rollback();
            }
        }

        public void Dispose() // don't know where to call this to see if it will solve my problem
        {
            if (session.IsOpen)
            {
                session.Close();
            }

        }

Ответы [ 2 ]

4 голосов
/ 02 января 2012

У каждого есть мнение, как использовать хранилище, что абстрагировать и т. Д. У Айенде Рахиен есть несколько хороших постов по этому вопросу: Архитектура в бездне судьбы: зло уровня абстракции хранилища и Хранилище - новый синглтон .Это дает вам довольно веские причины, почему вы не должны пытаться создать еще одну абстракцию поверх ISession NHibernate.

2 голосов
/ 02 января 2012

Особенность NHibernate в том, что он дает вам больше всего, если вы не пытаетесь абстрагировать его. Зависимость уровня обслуживания от NHibernate - это не обязательно плохо. Он дает вам контроль над сессиями, кэшированием и другими функциями NHibernate и, таким образом, позволяет повысить производительность, не говоря уже о том, чтобы избавить вас от всего избыточного кода переноса, который вы упомянули.

...