2010-10-21 74 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创建过滤器,并为我处理分页。

也许这样的系统可以为你工作。