Reputation: 379
I am using PagedList
to display paging on my search payment results page. I want to display only 5 payments on each page. The search criteria I am testing returns 15 records. I am expecting only 5 records on first page with page numbers 1,2,3 at bottom. I see the page numbers as expected at the bottom but all 15 records get displayed on every page. I have debugged the code and found out that StaticPagedList
function is returning 15 records instead of 5. My controller action code is as given below:
public ViewResult ViewPayment(int? billerId, int? billAccount, int? page)
{
var pageIndex = (page ?? 1) - 1;
var pageSize = 5;
List<Payment> paymentList = new List<Payment>();
paymentList = _paymentBusiness.GetPayments(billerId, billAccount);
var paymentsAsIPagedList = new StaticPagedList<Payment>(paymentList, pageIndex + 1, pageSize, paymentList.Count);
ViewBag.OnePageOfPayments = paymentsAsIPagedList;
return View(paymentList);
}
Please let me know if I have mistaken anything.
Upvotes: 1
Views: 2733
Reputation: 168
An alternate approach to using PagedList (which does not provide async methods), is to use DataTables.net (https://datatables.net).
It is a client side javascript framework for paged tables and can be configured down to very low levels. This would allow you to do what you need, and also have the ability for custom sorting, caching, searching, and many other features out of the box.
Just a suggestion, as I have used PagedList library myself in the past, and since discovering DataTables.Net, I have not looked back. Great library, and makes your life easy.
Upvotes: 0
Reputation: 58733
You should be querying only 5 records from your business layer. Right now you are not passing the page number or anything there. It's a bit of a waste to query all of them if you are going to only display some of them anyway.
public ViewResult ViewPayment(int? billerId, int? billAccount, int? page)
{
int pageNum = page ?? 1;
int pageSize = 5;
IPagedList<Payment> paymentPage = _paymentBusiness.GetPayments(billerId, billAccount, page, pageSize);
return View(paymentPage);
}
// Business layer
public IPagedList<Payment> GetPayments(int? billerId, int? billAccount, int page, int pageSize)
{
IQueryable<Payment> payments = db.Payments.Where(p => ....).OrderBy(p => ...);
return new PagedList<Payment>(payments, page, pageSize);
}
I would suggest you do something like the above. Change it so the business/data layer gives you back the paged list. It can get the 5 results, and the total count with two queries, and return your controller the page model.
The example gets a page using PagedList<T>
which runs Skip() and Take() internally. Remember to order your results before creating the page.
Importantly, now we do not fetch all the items from the database, only the small subset we are interested in.
If you are using e.g. ADO.NET that requires you to use plain SQL, you can use a query like:
SELECT * FROM Payments ORDER BY id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
Offset should be set to (page - 1) * pageSize
, and the number after FETCH NEXT is the page size. Note this only works on SQL Server 2012+. Other databases have similar abilities.
Also, with ADO.NET you will have to make the two queries needed manually (page + total count), and use StaticPagedList
instead of PagedList
, which allows you to give it the subset directly.
Upvotes: 3