2012-01-01 69 views
5

我想知道我的服务层应该知道我的存储库有多少?在过去的项目中,我总是返回列表并为每个需要的东西提供了一个方法。与NHibernate的库模式?

因此,如果我需要返回所有具有5将是方法Id的行。我有创建,更新,删除和其他NHibernate选项的通用资料库,但查询我不。

现在我开始为我拔腿就跑到具有为每个个案这么多方法的问题,使用起来更加的IQueryable。

说,如果我需要返回所有具有一定的编号,需要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(); 
      } 

     } 

回答

4

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

+0

我会更多地关注它。得到我的是我喜欢服务层不知道关于数据库的任何事情的想法,这使得单元测试(如果我需要的话)更容易并且易于切换出ORM。你如何处理这些情况? – chobo2 2012-01-02 22:15:32

+0

我也想知道如果我摆脱了仓库是否有一点指向我的工作单位班呢?请参阅编辑 – chobo2 2012-01-02 23:14:45

+0

您可以使用UnitOfWork来包装会话,甚至直接使用NH会话。至于单元测试,您可以使用内存数据库进行单元测试**,使用** NHiberate。这里有一篇关于Ayende的文章:http://ayende.com/blog/3983/nhibernate-unit-testing – 2012-01-03 06:27:08

2

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

+1

添加到这样的回答:NHibernate的会话是的UnitOfWork – ivowiblo 2012-01-02 23:36:00

+1

这就是为什么我想知道如果有一个点到的UnitOfWork类我,如果我不使用存储库模式做? – chobo2 2012-01-03 18:50:31