问题
I have an Action in my Controller to get a list of MyObjectViewModels
.
Inside that Action method, I call a method (Service layer) that fetches the relevant Models by applying a bunch of LINQ
methods and returns a IQueryable<MyObject>
.
Then I do some sorting on the returned IQueryable
and afterwards, ideally, I would perform a .Skip(...).Take(25)
in the resulting IQueryable
, convert it to a List, iterate over the 25 MyObject
elements and convert them into my MyObjectViewModels
class. I'd then return a PagedList
with those ViewModels:
public ActionResult MyAction(...parameters...)
{
// Supose this returns 100000 records...
IQueryable<MyObject> myObjs = _myService.GetMyObjects(...some params...);
// Sort and take only 25 (apply paging)
IQueryable<MyObject> mySortedAndPagedObjs = myObjs.OrderBy(...);
mySortedAndPagedObjs = mySortedAndPagedObjs.Skip(...).Take(25);
List<MyObject> myObjsList = mySortedAndPagedObjs.ToList();
List<MyObjectViewModel> myVMList = new List<MyObjectViewModel>();
// *** Conversion loop ***
foreach(MyObject myObj in myObjectList)
{
// ... convert the 25 MyObject to MyObjectViewModel
// and add them to the myVMList...
}
// Return a View with the PagedList
return View(myVMList.ToPagedList(pageNumber, pageSize));
// --> The PagedList will not "know" that it is looking at 25 records of a 100000 long list!
}
This, seems incompatible with the PagedList.MVC approach, which expects the ToPagedList()
method to receive the entire set of objects (not just the 25 - I assume it internally calls the .Skip().Take()
call itself). That would, however, force me to apply that conversion loop on the entire set of MyObject (!!) when I'd rather just do it for the 25 items I want to return at a time...
How can I get my PagedList
to show the ViewModels
chosen from a subset (e.g. 25 records) of a table with lots of data?
回答1:
This was actually a case of RTFM and I came up with the solution as I re-read the documentation when I was finished with my question. I'll post the Q&A anyway as it might be useful to someone in the future.
In order to accomplish the above scenario, I had to create and return a StaticPagedList.
In some cases you do not have access something capable of creating an IQueryable, such as when using .Net's built-in MembershipProvider's GetAllUsers method. This method offers paging, but not via IQueryable. Luckily PagedList still has your back (note the use of StaticPagedList):
In my case, that means:
public ActionResult MyAction(...parameters...)
{
// ... same as above ...
// Create a StaticPagedList
StaticPagedList<MyObjectViewModel> staticPagedList = new StaticPagedList<MyObjectViewModel>(myVMList , pageNumber + 1, pageSize, myObjs.Count());
// Return a View with the StaticPagedList
return View(myStaticPagedList);
}
来源:https://stackoverflow.com/questions/27982394/pagedlist-working-with-viewmodels-and-skip-take