Dapper - 具有单个返回值的多重映射

Ben*_*ter 7 dapper

下面是我用来返回分页对象列表的代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但这意味着我必须两次定义我的标准,一次用于计数查询,一次用于结果集查询.我可以只执行一个查询,而不是诉诸字符串连接:

        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";
Run Code Online (Sandbox Code Playgroud)

但是,我似乎无法使用Dapper进行映射.我不能使用与上面相同的方法,因为没有多个结果.我尝试过使用多映射,但是希望返回一个IEnumerable.

我将如何映射到以下内容?

    public class PostList
    {
        public IEnumerable<PostModel> Posts;
        public int TotalCount { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢

Sam*_*ron 6

嗯......你不会......

你必须修改你的PostModel以包含一个TotalCount属性......这真的很难看.或者执行动态并将其重新映射到一个Select也很难看的地方.

你看,你回来计数(*)N次count(*) over()...这是一个黑客,使用这个黑客不一定更快.我测量它比在某些场景中运行双查询慢,特别是你可以快捷一些索引,select count(*)因为你没有选择所有列.此外,hack禁用某些分页优化,例如您无法添加select top N到查询中.

我对分页查询的建议是获得正确的索引,这是关键.测量perf并查看此hack是否真正有用(当正确的索引到位时).

我关注字符串连接的问题,但您总是可以为此定义一般辅助方法.