2010-10-02 41 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

相關問題