在这个问题上有几个类似的问题,我还没有找到足够的理由来决定走哪条路。
真正的问题是abstract the NHibernate using a Repository pattern或not是否合理?
似乎抽象它背后的唯一原因是如果需要的话,让自己选择用不同的ORM替换NHibernate。但是创建存储库和抽象查询看起来像添加另一层,并手工完成大部分管道。
一个选项是将public IQueryable<T>
用于业务层并使用LINQ,但根据我的经验,LINQ支持仍然没有在NHibernate中完全实现(查询根本不能按预期工作,我讨厌开支调试框架的时间)。
尽管在我的业务层中引用NHibernate会伤害我的眼睛,但它本身应该是数据访问的抽象,对吗?
你对此有何看法?
答案 0 :(得分:5)
好静悄悄。几天前我也在考虑他们。
实际上,尝试NHibernate 3.0 alpha(或当前的trunk),它的新LINQ提供程序比以前的提供程序要大得多。 (到目前为止,我只发现了一种无法正常工作的方法,但如果遇到默认情况下不支持的内容,则可以挂钩自己的机制。) 使用当前主干我没有问题(但是?)。您可以在http://www.hornget.net/packages/站点上找到“夜间”构建,以及针对它的FluentNHibernate构建。如果您知道如何使用它,Fluent确实可以提高您的工作效率。 SO社区really helped me with that也是。
如果你的业务层可以直接依赖于NHibernate,或者你正在编写一个较小的应用程序,如果没有这种抽象,它仍然可以维护,那么你就可以不使用存储库模式了。但是,如果你做得对,它可以为你节省大量的冗余编码。
抽象它的原因不仅有用,因为之后您可以将NHibernate替换为另一个ORM,但由于名为Separation of Concerns的概念,这是一个很好的做法。您的业务逻辑层不应该关心或知道如何访问它使用的数据。这使得维护应用程序或其不同的层更容易,这也使团队协作更容易:如果X创建数据访问层,并且Y编写业务逻辑,则他们不必详细了解彼此的工作。
公开IQueryable<T>
是一个非常好的主意,而这正是许多存储库实现正在做的事情。 (我也是,虽然我更喜欢在静态类中编写它。)
当然,如果您愿意,您将不得不公开一些插入或更新实体的方法,或者开始和提交事务的方法。 (BeginTransaction应该只返回IDisposable
以避免泄漏NHibernate接口,这样就可以了。)
我可以给你一些指示:查看SharpArchitecture或FubuMVC Contrib的实现,以获得有关如何做到这一点的一些想法,这是how I solved it。
答案 1 :(得分:1)
我只想说一句大话!有一个存储库模式,保持抽象!
答案 2 :(得分:1)
我个人更喜欢将NHibernate抽象为存储库模式。原因是我可能仍然有其他存储库实现用于缓存,模拟单元测试等。我也使用IQueryable与我的存储库,虽然我使IRepository扩展IQueryable而不是在IQueryable类型的IRepository上公开属性。
另一个存储点。有些人建议不要使它具有通用性并在方法级别具有类型标识(即repository.Load)。但是,这假设将有一个知道如何处理所有类型的存储库。我不是这个单一存储库的概念的忠实粉丝。如果你正在处理多个数据库怎么办?还是多个持久性机制?或者某些数据类型保持相当静态并且可以缓存,但其他数据类型则不能。这就是为什么我喜欢每种类型的单独的存储库实例。