PagedList working with ViewModels and .Skip().Take()

岁酱吖の 提交于 2019-12-11 08:53:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!