使用NHibernate的存储库模式?

时间:2012-01-01 22:44:44

标签: nhibernate repository-pattern

我想知道我的服务层应该知道我的存储库有多少?在过去的项目中,我总是返回列表,并为我需要的每件事提供方法。

因此,如果我需要返回ID为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 个答案:

答案 0 :(得分:4)

每个人都有一个如何使用存储库的意见,抽象的内容等.Ayende Rahien关于这个问题的帖子很少:Architecting in the pit of doom: The evils of the repository abstraction layerRepository is the new Singleton。那些给你一些很好的理由,为什么你不应该尝试在NHibernate的ISession之上创建另一个抽象。

答案 1 :(得分:2)

关于NHibernate的事情是,如果你不试图将它抽象出来,它会给你最多的东西。使服务层依赖于NHibernate并不一定是件坏事。它使您可以控制会话,缓存和其他NHibernate功能,从而使您能够提高性能,更不用说让您远离所提到的所有冗余包装代码。