Repository Pattern with NHibernate?

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

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

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

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

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

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

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

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

Edit

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

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();
            }

        }
5
задан chobo2 2 January 2012 в 23:15
поделиться