小巧玲珑的 - 有一个返回值
问题描述:
多映射下面是我使用的返回对象的分页目录代码:小巧玲珑的 - 有一个返回值
string query2 = @"
select count(*) as TotalCount from blogposts p where p.Deleted = 0 and p.PublishDate <= @date
select * from (
select p.*,
row_number() over(order by publishdate desc) as rownum
from blogposts as p
where p.Deleted = 0 and p.PublishDate <= @date
) seq
where seq.rownum between @x and @y";
using (var cn = new SqlConnection(connectionString))
{
cn.Open();
using (var multi = cn.QueryMultiple(query2, new { x= lower, y = upper, date = DateTime.UtcNow }))
{
var totalCount = multi.Read<int>().Single();
var posts = multi.Read<PostModel>().ToList();
return new PagedList<PostModel>(posts, page, pageSize, x => totalCount);
}
}
虽然这个工作,它意味着我必须定义两次我的标准,一次用于计数查询,一次用于结果集查询。而不是诉诸字符串连接,我可以只执行一个查询:
string query = @"
select * from (select p.*,
row_number() over(order by publishdate desc) as rownum,
count(*) over() as TotalCount
from blogposts as p) seq
where seq.rownum between @x and @y";
不过,我似乎不能够映射这个小巧玲珑的使用。我无法使用与上面相同的方法,因为没有多个结果。我试过使用多映射,但是这期望返回一个IEnumerable。
我将如何映射到以下内容?
public class PostList
{
public IEnumerable<PostModel> Posts;
public int TotalCount { get; set; }
}
感谢
本
答
嗯......你不会......
你将不得不修改你的PostModel到包括财产共TOTALCOUNT ...这是真的丑陋。或者执行动态并重映射到Select
,这也很丑陋。
你看,你正在返回计数(*)N次与count(*) over()
......这是一个黑客攻击,使用这种攻击不一定更快。我测量过它比在某些情况下运行双查询要慢,特别是您可以在select count(*)
中缩短某些索引,因为您没有选择所有列。另外,hack会禁用某些分页优化,例如,您不能将select top N
添加到查询中。
我对分页查询的建议是获得索引权,这是关键。测量perf并查看这个破解是否真的有帮助(当正确的索引到位时)。
我关注字符串连接的问题,但您始终可以为其定义一般帮助程序方法。
感谢您的反馈意见。我想我会坚持双重查询,然后建立一些帮手以保持干燥。 – 2011-06-02 15:09:50