public ActionResult Index(int ehrId, int? page)
{
EHR ehr = ehrRepository.Find(ehrId);
if (ehr.UserName != User.Identity.Name)
return View("Invalid Owner");
const int pageSize = 5;
var physicaltests = ehr.PhysicalTests.OrderByDescending(test => test.CreationDate);
List<PhysicalTestListItem> physicalTestsVM = new List<PhysicalTestListItem>();
Mapper.Map(physicaltests, physicalTestsVM);
var paginatedTests = new PaginatedList<PhysicalTestListItem>(physicalTestsVM, page ?? 0, pageSize);
return View(paginatedTests);
}
this is the Pagination Class (at least whats relevant of it)
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(IEnumerable<T> source, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = source.Count();
TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
}
}
Im almost positive that this code is most definitely not doing what I want.. I dont want to have EF return all the records and then filter and paginate in memory…. at the same time Im not sure how to fix it.
Please help.
That code is definitely paging on the client side (You are using IENumerable, not IQuerable, so the execution of the query is not deferred).
If you want paging in the database, add your paging code to the EF call:
Other thoughts:
You could pass the EF query result to PaginatedList, and refactor it to use IQueryable instead of IEnumerable. This would let you keep the PaginatedList container…However, this is a leaky abstraction of EF and causes it to leak database type code into your frontend.
I usually implement database access in a repository layer and expose a method that returns IEnumerable. The controller only interacts with this method…Something like: