Using MultiQuery
使用综合查询(MultiQuery)
就像使用MultiCriteria可以将几个ICriteria和QueryOver查询组合到一个数据库交互中一样,我们可以使用MultiQuery来组合几个HQL查询.尤其是在数据库和应用程序分布在不同的机器上的情况下,与数据库的每次交互的开销都是非常大的.因此,以这种方式将查询结合,可以很大程度上提高应用程序的性能.本节介绍如何使用一个MultiQuery查询来获取产品数和产品结果的页面.
步骤
1. 完成本章简介中的通用步骤.
2. 在Queries类中,添加下面的结构: View Code
public struct PageOf{ public int PageCount; public int PageNumber; public IEnumerable PageOfResults;}
3. 在Queries类中,添加下面的方法:
View Code
public PageOfGetPageOfProducts( int pageNumber, int pageSize){ var skip = (pageNumber - 1) * pageSize; var countQuery = GetCountQuery(); var resultQuery = GetPageQuery(skip, pageSize); var multiQuery = _session.CreateMultiQuery() .Add ("count", countQuery) .Add ("page", resultQuery); var productCount = ((IList )multiQuery .GetResult("count")).Single(); var products = (IList )multiQuery .GetResult("page"); var pageCount = (int) Math.Ceiling( productCount/(double) pageSize); return new PageOf () { PageCount = pageCount, PageOfResults = products, PageNumber = pageNumber };}private IQuery GetCountQuery(){ var hql = @"select count(p.Id) from Product p"; return _session.CreateQuery(hql);}private IQuery GetPageQuery(int skip, int take){ var hql = @"from Product p order by p.UnitPrice asc"; return _session.CreateQuery(hql) .SetFirstResult(skip) .SetMaxResults(take);}
4. 在Program.cs中, 为RunQueries方法添加下述代码:
View Code
static void RunQueries(ISession session){ var queries = new Queries(session); var result = queries.GetPageOfProducts(1, 2); var heading = string.Format("Page {0} of {1}", result.PageNumber, result.PageCount); Show(heading, result.PageOfResults);}
5. 编译运行,结果如下图所示:
原理
这个示例中,我们创建了两个HQL查询.第一个返回所有products的计数,要注意,HQL的count返回的是一个Int64或long类型.
第二个查询返回了一个单独的products页面.我们使用SetFirstResult设置结果的起始位置.例如,SetFirstResult参数值为0时,将返回所有的结果,参数值是10的时候,将会跳过前10个结果,返回第11个和其后的结果.结合使用SetFirstResult和SetMaxResults来返回结果的一个单独页面.使用 .SetFirstResult(10).SetMaxResults(10)时,将返回第11个到第20个product . 在将每个查询添加到MultiQuery对象时,为其指定了一个标签或是名字,而泛型参数指定了返回的list的类型.和MultiCriteria一样,无法直接返回一个单独的实体或标量值.这个示例中,count查询将返回一个包含一个条目的Int64s列表,page查询将返回一个Products列表.我们将使用LINQ to Objects的Single()方法来获取实际的统计值. 在调用GetResults的时候,我们再一次使用标签来返回一个特定的结果集.第一次调用GetResults时,会在一个单独的批处理执行所有的查询,而后面的每次调用只会返回一个已经执行过的查询结果.