使用 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:
- 创建分页列class:
public class PagingColumns{public int Id { get; set; }public int? TotalCount {get;set;}}
- 在您的查询中,添加这两列:
" -99 as Id, TotalCount = COUNT(1) OVER() "
- “Id”将被伪造以拆分映射上的列。
- TotalCount 将为您提供查询记录的总数。
- 在查询底部添加分页选项:
"ORDER BY OneOfYourTables.Id DESC OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY "
Query/mapping 时间:
PagingColumns pagingColumns;
conn.Query<YourModelA, PagingColumns, YourModelA>(sql, (m, p) =>
{
yourModelsList.Add(m);
pagingColumns = p;
return m;
});
PagingColumns 现在将有您的 totalCount.
作为技巧,您可以在不需要分页时伪造“TotalCount”值。
我正在使用 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:
- 创建分页列class:
public class PagingColumns{public int Id { get; set; }public int? TotalCount {get;set;}}
- 在您的查询中,添加这两列:
" -99 as Id, TotalCount = COUNT(1) OVER() "
- “Id”将被伪造以拆分映射上的列。
- TotalCount 将为您提供查询记录的总数。
- 在查询底部添加分页选项:
"ORDER BY OneOfYourTables.Id DESC OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY "
Query/mapping 时间:
PagingColumns pagingColumns; conn.Query<YourModelA, PagingColumns, YourModelA>(sql, (m, p) => { yourModelsList.Add(m); pagingColumns = p; return m; });
PagingColumns 现在将有您的 totalCount.
作为技巧,您可以在不需要分页时伪造“TotalCount”值。