分页问题:返回正文中的总计数和总页数,而不添加到正在获取的其他数据
Posted
技术标签:
【中文标题】分页问题:返回正文中的总计数和总页数,而不添加到正在获取的其他数据【英文标题】:Pagination issue: returning total count and total pages in body, without adding to other data that is being fetched 【发布时间】:2021-11-16 17:31:32 【问题描述】:我有一个搜索功能,我可以在其中填写 exempel 的值:注册号并获取有关它的数据,或者如果我不输入任何参数,我将获取所有数据,每页 100 行.现在,我还创建了一种计数,我可以在其中查看总共有多少行,以及如果每页有 100 行,这将是多少页。问题是我想返回请求正文中的总计数和总页数,例如,请求答案的外观如下:
[
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-20",
"requestID": 118095,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 54",
"workshop": "Workshop 55",
"asignee": null,
"claimId": "387385",
"vinnumber": ""
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-203",
"requestID": 118094,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 10",
"workshop": "Workshop 3",
"asignee": null,
"claimId": "387384",
"vinnumber": ""
]
而不是在每个答案中添加 2 行的总计数和总页数,我只想在正文中请求答案的顶部得到这些,所以它可能看起来像这样:
[
"totalcount" : "300",
"totalpages" : "3"
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-20",
"requestID": 118095,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 54",
"workshop": "Workshop 55",
"asignee": null,
"claimId": "387385",
"vinnumber": ""
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-203",
"requestID": 118094,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 10",
"workshop": "Workshop 3",
"asignee": null,
"claimId": "387384",
"vinnumber": ""
]
这是我使用的两种方法(一种用于搜索,一种用于计数)
public async Task<IEnumerable<GetRequestModelOut>> GetRequest(GetRequestModel model, int pageNumber = 1)
var parameters = new DynamicParameters();
parameters.Add("@RegNumber", model.RegNumber == string.Empty ? null : model.RegNumber);
parameters.Add("@Vinnumber", model.Vinnumber == string.Empty ? null : model.Vinnumber);
parameters.Add("@CountryID", model.CountryId == -1 ? (int?)null : model.CountryId);
parameters.Add("@assigneid", model.AssigneId == string.Empty ? null : model.AssigneId);
parameters.Add("@dateFrom", model.dateFrom);
parameters.Add("@dateTo", model.dateTo);
parameters.Add("@pageSize", model.pageSize);
parameters.Add("@PageNumber", model.PageNumber);
int number = await getCount1(model);
model.totalCount = number;
model.totalPages = (int)Math.Ceiling(model.totalCount / (double)model.pageSize);
var getReq1 = await _sqlconnection.QueryAsync<GetRequestModelOut>($@"
SELECT model.totalCount as totalCount, model.totalPages as totalPages,
ClaimHandlingStatus.Name as ClaimHandlingStatus,
Request.CreatedDate as requestDate,
Request.ID as RequestID, Contract.CountryID,
RegNumber, Product.Name as produkt,
Retailer.Name as workshop, Claim.CreatedBy as UserID, Claim.ID as claimId,
Vinnumber
FROM Request
INNER JOIN RequestCrossClaim ON Request.ID = RequestCrossClaim.RequestID
INNER JOIN Claim ON RequestCrossClaim.ClamID = Claim.ID
INNER JOIN Contract ON Request.ContractID = Contract.ID
INNER JOIN Vehicle ON Contract.VehicleID = Vehicle.ID
INNER JOIN Product ON Contract.ProductID = Product.ID
INNER JOIN Retailer ON Contract.RetailerID = Retailer.ID
INNER JOIN ClaimHandlingStatus ON Claim.ClaimHandlingStatusID = ClaimHandlingStatus.ID
where (@RegNumber IS NULL OR RegNumber = @Regnumber)
AND (@Vinnumber IS NULL OR Vinnumber = @Vinnumber)
AND (@CountryID IS NULL OR Contract.CountryID = @CountryID)
AND (@assigneid IS NULL OR Claim.CreatedBy = @assigneid)
AND (@dateFrom IS NULL OR Request.CreatedDate BETWEEN @dateFrom AND @dateTo)
ORDER BY requestDate desc OFFSET @pageSize * (@PageNumber-1) ROWS FETCH NEXT @pageSize ROWS ONLY",
parameters);
return getReq1;
这是计数:
public async Task<int> getCount1(GetRequestModel model)
// Count method for Pagination in GetRequest
var parameters = new DynamicParameters();
parameters.Add("@RegNumber", model.RegNumber == string.Empty ? null : model.RegNumber);
parameters.Add("@Vinnumber", model.Vinnumber == string.Empty ? null : model.Vinnumber);
parameters.Add("@CountryID", model.CountryId == -1 ? (int?)null : model.CountryId);
parameters.Add("@assigneid", model.AssigneId == string.Empty ? null : model.AssigneId);
parameters.Add("@dateFrom", model.dateFrom);
parameters.Add("@dateTo", model.dateTo);
parameters.Add("@pageSize", model.pageSize);
parameters.Add("@PageNumber", model.PageNumber);
var getCount = await _sqlconnection.QueryAsync<int>($@"
SELECT TOP 2000(Claim.ID)
FROM Request
INNER JOIN RequestCrossClaim ON Request.ID = RequestCrossClaim.RequestID
INNER JOIN Claim ON RequestCrossClaim.ClamID = Claim.ID
INNER JOIN Contract ON Request.ContractID = Contract.ID
INNER JOIN Vehicle ON Contract.VehicleID = Vehicle.ID
INNER JOIN Product ON Contract.ProductID = Product.ID
INNER JOIN Retailer ON Contract.RetailerID = Retailer.ID
INNER JOIN ClaimHandlingStatus ON Claim.ClaimHandlingStatusID = ClaimHandlingStatus.ID
where (@RegNumber IS NULL OR RegNumber = @Regnumber)
AND (@Vinnumber IS NULL OR Vinnumber = @Vinnumber)
AND (@CountryID IS NULL OR Contract.CountryID = @CountryID)
AND (@assigneid IS NULL OR Claim.CreatedBy = @assigneid)
AND (@dateFrom IS NULL OR Request.CreatedDate BETWEEN @dateFrom AND @dateTo)
", parameters);
return getCount.Count();
正如您在第一种方法中看到的,我目前正在将总计数和页面发送到模型,这意味着我当前的响应如下所示:
[
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-20",
"requestID": 118095,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 54",
"workshop": "Workshop 55",
"asignee": null,
"claimId": "387385",
"vinnumber": "",
"totalCount": 2,
"totalPages": 1
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-203",
"requestID": 118094,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 10",
"workshop": "Workshop 3",
"asignee": null,
"claimId": "387384",
"vinnumber": "",
"totalCount": 2,
"totalPages": 1
]
而且我认为这是不必要的,因为它足以获得总计数和页面一次。顺便说一下,模型的外观如下;
public class GetRequestModel
public int CountryId get; set; = -1;
public string AssigneId get; set; = "";
[StringLength(50)]
public string RegNumber get; set; = "";
[StringLength(50)]
public string Vinnumber get; set; = "";
public DateTime? dateFrom get; set; = null;
public DateTime? dateTo get; set; = null;
// Pagination information
public int pageSize get; set; = 100;
public int PageNumber get; set; = 1;
public int totalCount get; set; = 0;
public int totalPages get; set; = 0;
以及获取数据的模型:
public class GetRequestModelOut
public string ClaimHandlingStatus get; set;
public DateTime RequestDate get; set;
public int RequestID get; set;
public int CountryID get; set;
public string RegNumber get; set;
public string Produkt get; set;
public string Workshop get; set;
public string Asignee get; set;
public string claimId get; set;
public string Vinnumber get; set;
public int totalCount get; set; = 0;
public int totalPages get; set; = 0;
还有控制器:
[HttpGet]
public async Task<IActionResult> GetRequest([FromQuery] GetRequestModel model, int pageNumber)
if (!ModelState.IsValid)
return BadRequest(ModelState);
try
var list = await _request.GetRequest(model, pageNumber);
return Ok(list);
catch (Exception e)
return BadRequest(e.Message);
return Ok();
现在我尝试做一些类似的事情:
var metadata = new
model.totalCount,
model.totalPages
;
在控制器中,但这仍然留下了关于如何将这两个值返回到响应 body 的问题?感谢您的任何意见,因为我现在感觉有点卡住了。
【问题讨论】:
This discussion 似乎解释了如何确定总行数(结果集中的TempCount
列)而不会在大型数据集上出现性能问题
@Pieterjan 谢谢你,我会调查的。我在数据库上创建了 indexex,所以性能还可以而且不慢,但它可能会更好,在不同的方法上选择和计算相同的查询并不是最好的主意哈哈
【参考方案1】:
我认为,更好的解决方案是将所有这些答案+摘要详细信息实际包装在单独的对象中,将它们组合在一起。喜欢:
public class SummaryModel
public int totalCount get; set; = 0;
public int totalPages get; set; = 0;
public class GetRequestModelOut
// Things from your normal out-model
// WITHOUT totalCount and totalPages
public class ResultModel
public SummaryModel Summary get; set;
public IEnumerable<GetRequestModelOut> Models get; set;
当您将调用/返回结果时,您只需将对象放在一起,如下所示:
public async Task<ResultModel> GetRequest(GetRequestModel model, int pageNumber = 1)
var parameters = new DynamicParameters();
parameters.Add("@RegNumber", model.RegNumber == string.Empty ? null : model.RegNumber);
parameters.Add("@Vinnumber", model.Vinnumber == string.Empty ? null : model.Vinnumber);
//add all other params
int totalCount = await getCount1(model);
int totalPages = (int)Math.Ceiling(totalCount / (double)model.pageSize);
var summary = new Summary()
totalCount = totalCount,
totalPages = totalPages
;
var models = await _sqlconnection.QueryAsync<GetRequestModelOut>(/*query*/);
return new ResultModel()
Summary = summary,
Models = models
;
生成的 JSON 如下所示:
"Summary":
"totalCount": 300,
"totalPages": 3
,
"Models": [
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-20",
"requestID": 118095,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 54",
"workshop": "Workshop 55",
"asignee": null,
"claimId": "387385",
"vinnumber": ""
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-203",
"requestID": 118094,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 10",
"workshop": "Workshop 3",
"asignee": null,
"claimId": "387384",
"vinnumber": ""
]
【讨论】:
【参考方案2】:你的预期输出是关闭考虑这个:
"totalcount" : "300",
"totalpages" : "3",
"items" : [
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-20",
"requestID": 118095,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 54",
"workshop": "Workshop 55",
"asignee": null,
"claimId": "387385",
"vinnumber": ""
,
"claimHandlingStatus": "HANDLING",
"requestDate": "2021-09-203",
"requestID": 118094,
"countryID": 1,
"regNumber": "CNK258365",
"produkt": "Produkt 10",
"workshop": "Workshop 3",
"asignee": null,
"claimId": "387384",
"vinnumber": ""
]
总计数和总页数不应是项目的一部分。不过,这样你发送的是一个作业而不是一个 jarray。
【讨论】:
以上是关于分页问题:返回正文中的总计数和总页数,而不添加到正在获取的其他数据的主要内容,如果未能解决你的问题,请参考以下文章
怎样使word页码中的总页数不包括封面和目录(文章正文中包含很多节)
Asp.net的DataPager控件如何显示当前页的数据条数、总条数和总页数?
jquery ajax 调用kkpager插件 异步加载重新生成分页后,点击页数还是跟首次加载一样