使用 dapper 进行分页的 TotalCount

TotalCount for paging with dapper

我正在使用 dapper 将结果集从存储过程获取到对象列表中,然后 return 将其作为 json:

发送给客户端
public IHttpActionResult Test()
    {
        List<ProductPreview> gridLines;
        var cs = ConfigurationManager.ConnectionStrings["eordConnection"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(cs))
        {
            gridLines = conn.Query<ProductPreview>("dbo.myStoredProcedure", new { userID = 1 },
             commandType: CommandType.StoredProcedure).ToList();
        }
        var totalCount = gridLines[0].MaxCount;//I need to know total count
        ....
        return Ok(gridLines);
    }

有效。 ProductPreview 类型对象的最后一个 属性 是 TotalCount,因为存储过程 return 的总计数是每行的列。 (第二个选项是存储过程 return 有两个记录集,但我不确定如何更改 dapper 以使用两个记录集)。有两个单独的查询不是一个选项。

在没有 totalCount 属性 的情况下 return gridLines json 对象到客户端的最佳方法是什么(因为它是开销)并将总计数从存储过程读取到某个变量? 将 gridLines 对象复制到没有 totalCount 属性 的其他对象也将是不必要的开销。

Dapper 允许您在单个查询中处理多个结果网格。

示例:

var sql = 
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";

using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
   var customer = multi.Read<Customer>().Single();
   var orders = multi.Read<Order>().ToList();
   var returns = multi.Read<Return>().ToList();
   ...
} 

您可能想以不同的方式处理这个问题,因为要求是获得一个 Result set 和一个 count,那么即使 QueryMultiple 有帮助,但它更适合用于multiple result sets,在这种情况下,您可以只计划使用 Dynamic Parameters,这可以帮助您添加 OutputParameter,而不仅仅是 InputParameter,因为您默认使用 Anonymous type 并执行 conn.Query<ProductPreview>,这将有助于接收类型 IEnumerable<ProductPreview> 的结果集,可以使用您的代码获取输出参数值以获取计数,如下所示:

public IHttpActionResult Test()
    {
        List<ProductPreview> gridLines;
        var cs = ConfigurationManager.ConnectionStrings["eordConnection"].ConnectionString;
        using (SqlConnection conn = new SqlConnection(cs))
        {
            DynamicParameters dynamicParameters = new DynamicParameters();

            dynamicParameters.Add("UserID",1,ParameterDirection.Input);

            // Fill the Count in this Parameter
            dynamicParameters.Add("Count",0,ParameterDirection.Output); 

            gridLines = conn.Query<ProductPreview>("dbo.myStoredProcedure", dynamicParameters,
             commandType: CommandType.StoredProcedure).ToList();

             var totalCount = dynamicParameters.Get<int>("Count");
        }

        ....
        return Ok(gridLines);
    }

我找到了一个“不错”的方法来做到这一点,稍微欺骗了 dapper:

  1. 创建分页列class:

public class PagingColumns{public int Id { get; set; }public int? TotalCount {get;set;}}

  1. 在您的查询中,添加这两列:

" -99 as Id, TotalCount = COUNT(1) OVER() "

  • “Id”将被伪造以拆分映射上的列。
  • TotalCount 将为您提供查询记录的总数。
  1. 在查询底部添加分页选项:

"ORDER BY OneOfYourTables.Id DESC OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY "

  1. Query/mapping 时间:

         PagingColumns pagingColumns;
         conn.Query<YourModelA, PagingColumns, YourModelA>(sql, (m, p) =>
         {
             yourModelsList.Add(m);
             pagingColumns = p;
             return m;
         });
    

PagingColumns 现在将有您的 totalCount.

作为技巧,您可以在不需要分页时伪造“TotalCount”值。