建模NHibernate查询

Seb*_*Piu 7 .net c# architecture nhibernate

通常我会将我的标准/ hql查询放在与实体相关的repository/dal类中,但最近我一直在考虑添加另一个表示查询内容的抽象,这样我就可以添加常见行为了.基类中的所有查询(例如分页)等.

所以这些是我的组成部分;

与nhibernate无关的通用接口:

public interface IQuery<T>
{
    IList<T> List();
    T Single();
}
Run Code Online (Sandbox Code Playgroud)

基于Criteria的查询的示例实现,可以使用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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里一个特定于域的查询看起来像:

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

    IGetVideosQuery AllTime { get; }
    IGetVideosQuery Today { get; }
    IGetVideosQuery LastWeek { get; }
}
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?你看到我可能会遇到的问题?谢谢!

Kei*_*thS 2

我的第一个建议是使用 Linq2NH,它在 NHibernate 2.1 及更高版本中可用。Session 公开了一种AsQueryable<T>()方法,您可以在该方法上构建 Linq 查询。这将允许您使用标准 Linq 扩展方法(包括用于实现分页 ( ) 的 Skip() 和 Take()myQuery.Skip(PageIdx*PageSize).Take(PageSize).ToList()以及用于过滤的Where 子句)随意附加条件和投影。这些查询中使用的 lambda 表达式和变量可以封装在某种 QueryInfo 类中,从而允许可重复、可持久的查询。