2010-10-21 64 views
7

通常我會把我的標準/ hql查詢放入與實體相關的存儲庫/ dal類中,但最近我一直在考慮添加另一個表示查詢的抽象,這會給我在基類中的所有查詢(例如分頁)中添加普通行爲的可能性等。建模NHibernate查詢

所以這些是我現在的組件;

通用接口不相關的NHibernate:

public interface IQuery<T> 
{ 
    IList<T> List(); 
    T Single(); 
} 

例實施基於標準的查詢,也可能出現相似的HQL查詢,或NHibernate的,LINQ查詢

public abstract class CriteriaQuery<T>: IQuery<T> 
{ 
    [Inject] 
    public ISessionFactory SessionFactory { protected get; set; } 

    protected ISession Session 
    { 
     get { return SessionFactory.GetCurrentSession(); } 
    } 

    protected abstract ICriteria Configure(ICriteria criteria); 

    [Transaction] 
    public virtual IList<T> List() 
    { 
     var criteria = Session.CreateCriteria(typeof (T)); 

     return Configure(criteria) 
       .List<T>(); 
    } 

    [Transaction] 
    public virtual T Single() 
    { 
     return Configure(Session.CreateCriteria(typeof(T))) 
       .UniqueResult<T>(); 
    } 
} 

並做了什麼這裏一個特定領域的查詢將如下所示:

public interface IGetVideosQuery: IQuery<Video> 
{ 
    IGetVideosQuery Page(int index); 
    IGetVideosQuery PageSize(int pageSize); 

    IGetVideosQuery AllTime { get; } 
    IGetVideosQuery Today { get; } 
    IGetVideosQuery LastWeek { get; } 
} 

任何對此有何想法?您可能遇到的問題可能會遇到? 謝謝!

+1

查看Fabio Maulo的「增強型」查詢對象,查看某個相關的結構:http://fabiomaulo.blogspot.com/2010/07/enhanced-query-object.html – DanP 2010-10-25 12:34:29

+0

@danp:謝謝! – 2010-10-25 12:43:43

回答

2

我的第一個建議是使用NHibernate 2.1及更高版本的Linq2NH。會話公開了一個可以構建Linq查詢的AsQueryable<T>()方法。這將允許您使用標準的Linq擴展方法附加標準和預測,包括Skip()和Take()來實現分頁(myQuery.Skip(PageIdx*PageSize).Take(PageSize).ToList())和Where子句進行過濾。這些查詢中使用的lambdas和變量可以封裝在某種QueryInfo類中,從而實現可重複的持久查詢。

4

我採取了不同的路徑,即CQS。它所做的就是將我的變異邏輯從我的查詢邏輯中分離出來。

現在,有關於如何執行此不同的想法,我選擇這一項:

  • 我所有的變異邏輯是使用命令狀DeactivateUserChangeRelationAddress激活。對於這個業務邏輯,我有像你所描述的正常倉庫;

  • 對於顯示數據,我使用完全管理的系統。通過這個系統,我描述了像Specification Pattern這樣的查詢。我描述了基表和字段。查詢系統爲我自動創建連接,並使用我提供過濾器的過濾器定義。

這個系統允許我保留我的資料庫的複雜了,因爲我沒有去想過濾器,用戶可以設置或ORDER BY的。顯示此數據的系統會自動使用Criteria創建過濾器,併爲我處理分頁。

也許這樣的系統可以爲你工作。