2010-10-02 37 views
0

我期待获得一些有关如何改进我的设计的反馈。具体来说,我不想为每个域对象创建一个新的存储库对象,但我也不想一遍又一遍重写会话和事务逻辑。Nhibernate体系结构 - 通用Nhibernate存储库可用于多种不同类型

为了缓解了需要编写的代码,以获得每个数据库事务我做我创建和通用的抽象类,看起来像这样一个新的会话和TRANSATION:

public class AbstractNHibernate<T> where T : class 
{ 

    public void Add<T>(T entity) 
    { 
     using(ISession session = NHibernateHelper.OpenSession()) 
     using (ITransaction transaction = session.BeginTransaction()) 
     { 
      session.Save(entity); 
      transaction.Commit(); 
     } 
    } 
} 

那是伟大的,但后来我不得不为我的每个域实体创建一个存储库,如下所示:

public class ConnectionModel : AbstractNHibernate<Connection> 
    { 
     public void SaveConnection(Connection conn) 
{ 
Add(conn); 
} 
    } 

我可能有很多这样的。有人可以提出一种不同的方法?

在此先感谢。

回答

2

你的仓库应(一般)没有打开的会话或执行交易。这应该在服务层或用户界面中完成。使用您当前的设计,无法让多个存储库参与同一个事务。您可以通过在存储库构造函数中要求ISession来实现此目的。

我也不喜欢每个对象模型中的一个存储库,更好的方法是将逻辑上的公共存储库函数分组在一起。例如,公司库可能有与公司和相关数据一起工作的方法 - CompanyType,CompanyStatus等。

0

我已经看到这种情况(以及我是如何做到这一点),是建立一个接口,创建Nhiberate类实现这个接口(库模式)

http://www.rosscode.com/blog/index.php?title=the_repository_pattern_andash_iarsquo_m_&more=1&c=1&tb=1&pb=1

也使用的方式规范模式允许将查询传递到存储库。更多信息可以在这里找到:

http://www.mostlyclean.com/category/NHibernate.aspx

要注意的事情是会话在别处创建,然后注入(通过)到库,我使用IoC容器,如温莎做到这一点。

HTH

0

也许我不理解你的问题?你似乎在问如何实现泛型,所以你不必为每个对象创建一个类型特定的类,而不是问一个nhibernate问题。

这里是一个简单的Repository,它接受任何类型的T,你只需从类签名中移除T并实例化即可。但请记住,这仅仅是一个会话封装,更像是一个工作单元而不是一个存储库。实现查询将需要一些工作来尝试通用。你可以使用类似这样的东西作为你需要复杂查询的子类型的基类,如果你只支持其他对象的非常基本的查询,也可以作为独立的实例。

/// <summary> 
/// Repository defines simple class with standard methods 
/// to accept and operate on any type. 
/// </summary> 
public class Repository 
{ 
    private ISession _session; 

    public ISession Session 
    { 
     get { return _session; } 
    } 


    /// <summary> 
    /// Save an entity. 
    /// </summary> 
    public void Save<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Save(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Update an entity 
    /// </summary> 
    public void Update<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Update(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Delete an entity 
    /// </summary> 
    public void Delete<T>(T entity) 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Delete(entity); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Retrieve an entity 
    /// </summary> 
    public T GetById<T>(Guid id) 
    { 
     Reconnect(_session); 
     try 
     { 
      return _session.Get<T>(id); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Method for flushing the session. 
    /// </summary> 
    public void Flush() 
    { 
     Reconnect(_session); 
     try 
     { 
      _session.Flush(); 
      _session.Clear(); 
     } 
     finally 
     { 
      Disconnect(_session); 
     } 
    } 

    /// <summary> 
    /// Reconnect to the session. Accept parameter so we can use anywhere. 
    /// </summary> 
    public void Reconnect(ISession session) 
    { 
     if (!session.IsConnected) 
     { 
      session.Reconnect(); 
     } 
    } 

    /// <summary> 
    /// Disconnect from the session. Accept parameter so we can use anywhere. 
    /// </summary> 
    public void Disconnect(ISession session) 
    { 
     if (session.IsConnected) 
     { 
      session.Disconnect(); 
     } 
    } 

    public Repository(ISession session) 
    { 
     _session = session; 
    } 

} 

}

+0

为什么所有的会话重新连接和断开? – dbones 2010-10-02 21:22:00

+0

我有和dbones一样的问题。 – Nick 2010-10-03 02:10:24

+0

没理由。每个动作周围的直接和明确的断开连接和重新连接都是来自DBA的一个策略要求,该DBA非常反ORM并试图压制整个概念。他被推翻了,但确实有足够的政治影响力来强加一些(通常是荒谬的)发展规则。对不起,任何混乱,一段时间后,它成为这样做事的习惯。 – Sisyphus 2010-10-03 17:56:31

相关问题