小巧玲珑的 - 有一个返回值

问题描述:

多映射下面是我使用的返回对象的分页目录代码:小巧玲珑的 - 有一个返回值

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并查看这个破解是否真的有帮助(当正确的索引到位时)。

我关注字符串连接的问题,但您始终可以为其定义一般帮助程序方法。

+0

感谢您的反馈意见。我想我会坚持双重查询,然后建立一些帮手以保持干燥。 – 2011-06-02 15:09:50