Gerald Hughes
Gerald Hughes

Reputation: 6159

Implementing IPagedList with my ViewModels

I'm using NuGet PagedList.Mvc on my ASP.NET MVC app, I want to return to view placesVM.ToPagedList(pageNumber, pageSize)

I tried to use PagedList<> instead of List<>.

The examples I checked, don't seem to match my scenario, or do they ?

Bellow you can find my actual code.

ViewModel

using PagedList;
using System.Collections.Generic;

namespace WhereWeDoIt.ViewModels
{
    public class PlacesIndexViewModel
    {
        public /*PagedList*/List<PlaceIndexViewModel> Places { get; set; }
        public string CurrentUserId { get; set; }
    }
}

Controller

public ActionResult Index(int? page)
{
    var config = new MapperConfiguration(cfg => cfg.CreateMap<Place, PlaceIndexViewModel>());
    var mapper = config.CreateMapper();

    var placesVm = new PlacesIndexViewModel { Places = new List<PlaceIndexViewModel>(), 
                                            CurrentUserId = User.Identity.GetUserId() };

    var placesBal = new PlaceBusinessLayer();
    var places = placesBal.GetAllPublic();

    placesVm.Places = mapper.Map<List<PlaceIndexViewModel>>(places);

    int pageSize = 3;
    int pageNumber = (page ?? 1);

    return View(placesVm/*.ToPagedList(pageNumber, pageSize)*/);
}

Upvotes: 0

Views: 1871

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239270

If you're mapping records from your database onto view models, then you need to utilize StaticPagedList.

Stephen had some good points for you, in general. Your repo method should return a queryable, rather than a list, as that will indeed materialize all the records before you can apply any paging logic. However, the same thing will still occur if you then use AutoMapper to map them onto view models. Instead, you must first limit your queryable:

var places = placesBal.GetAllPublic().Skip((pageNumber - 1) * pageSize).Take(pageSize);

You'll also need a separate query to get the total count. There's no way to do it all in one query, but a count query is fast. Here, you don't limit the queryset, because you want the total count, not just the total on the current page.

var totalPlaces = placesBal.GetAllPublic().Count();

Then, map it:

var mappedPlaces = mapper.Map<List<PlaceIndexViewModel>>(places);

Before finally newing up an instance of StaticPagedList with that:

placesVm.Places = new StaticPagedList<PlaceIndexViewModel>(mappedPlaces, pageNumber, pageSize, totalPlaces);

Upvotes: 3

Related Questions