2011-02-18 82 views
1

我有一个MVC项目,我试图设置一个很好的分页解决方案。NHibernate - 动态QueryOver参数

我有几个表在SQL Server中有几千行,我希望能够通过。如果我没有适用于分页的任何类型的过滤器,它的效果很好。这是我使用的是做到这一点的方法:

public virtual PagedList<T> GetPagedData(int startIndex, int count) { 
     var rowCount = session.CreateCriteria(typeof(T)).SetProjection(Projections.RowCount()).FutureValue<Int32>().Value; 
     var pageOfItems = session.CreateCriteria(typeof(T)).SetFirstResult(startIndex).SetMaxResults(count).List<T>(); 
     return new PagedList<T>(pageOfItems, startIndex, count, rowCount); 
    } 

我也想在查询,以进一步缩小结果向下传递,并返回一个新的分页表的能力。我至今是:

public virtual PagedList<T> GetPagedData<T>(int startIndex, int count, System.Linq.Expressions.Expression<Func<T, bool>> predicate) where T : class { 
     var rowCount = session.QueryOver<T>().Where(predicate).Select(Projections.RowCount()).FutureValue<Int32>().Value; 

     var pageOfItems = session.QueryOver<T>().Where(predicate).Skip(startIndex).Take(count).List<T>(); 
     return new PagedList<T>(pageOfItems, startIndex, count, rowCount); 
    } 

的调用,这将是这个样子:

networks = mRepository.GetPagedData<Network>(page ?? 1, pageSize, x => x.Name.Contains(q)); 

的问题是,它不喜欢“包含”表达。如果我做了一个完全匹配,它工作正常(x.Name == q),但我没有得到我后面的结果。

我用看到的异常 “包含” 是:

无法识别的方法调用:System.String:布尔包含(System.String)

有没有人有一个想法如何让这个动态地接受这样的表达式?我有一个基础知识库类,我已经把它放在这里,因为我会为其他几个表使用相同类型的行为。我可以为每个表格编写一个单独的方法,但如果可能的话,我宁愿动态地执行此操作。

感谢您的任何建议!

回答

3

QueryOver不是LINQ,它只接受一组非常有限的表达式。

我的建议是,你用Query替换QueryOver来改写你的LINQ方法。唯一的问题是,它是很难做到用未来的查询(见this answer了解详细信息)

这里有一个版本的计数,而未来:

public virtual PagedList<T> GetPagedData<T>(int startIndex, int count, 
       Expression<Func<T, bool>> predicate) where T : class 
{ 
    var query = session.Query<T>().Where(predicate); 
    var rowCount = query.Count(); 
    var page = query.Skip(startIndex).Take(count).List<T>(); 
    return new PagedList<T>(pageOfItems, startIndex, count, rowCount); 
} 
+0

感谢您的意见。这工作完美。我会研究那篇关于Future Query用法的文章,但我很高兴能在此期间使用它。 – Brosto 2011-02-18 19:06:54

0

随着QueryOver你必须使用扩展方法IsLike,所以x.Name.IsLike(q, MatchMode.Anywhere)