Search code examples
asp.netasp.net-mvcasp.net-coresortingpagination

Asp Core, How to use PagingList<T>.CreateAsync() with a viewModel?


I am working on a asp.net core 1.1 project and i want to create paging in my some views. I studied microsoft documents about paging in asp core but it is very simple mode with 1 table. In my view i use multi table and use a viewmodel to initialize it. I want to use PagingList<T>.CreateAsync() method to create paging but get error: can not convert from system.linq.Iqueryable<> to system.linq.IorderedQueryable<>

my action:

    [HttpGet]
    public async Task<IActionResult> Index(int? page)
    {
        List<BookListViewModel> model = new List<BookListViewModel>();
        var query = (from b in _context.books
                     join a in _context.authors on b.AuthorID equals a.AuthorId
                     join bg in _context.bookgroups on b.BookGroupID equals bg.BookGroupId


                     select new
                     {
                         b.BookId,
                         b.BookName,
                         b.BookPageCount,
                         b.BookImage,
                         b.AuthorID,
                         b.BookGroupID,
                         a.AuthorName,
                         bg.BookGroupName
                     });

        foreach (var item in query)
        {
            BookListViewModel objmodel = new BookListViewModel();

            objmodel.BookId = item.BookId;
            objmodel.BookName = item.BookName;
            objmodel.BookImage = item.BookImage;
            objmodel.BookPageCount = item.BookPageCount;
            objmodel.AuthorId = item.AuthorID;
            objmodel.BookGroupId = item.BookGroupID;
            objmodel.AuthorName = item.AuthorName;
            objmodel.BookGroupName = item.BookGroupName;

            model.Add(objmodel);

        }
        ViewBag.RootPath = "/upload/thumbnailimage/";
        int pageSize = 3;
        int pageNumber = (page ?? 1);

        return View(await PagingList<BookListViewModel>.CreateAsync(model.AsQueryable() , pageNumber, pageSize));
    }

I have not yet written anything about paging in index view and it is a simple list of viewmodel


Solution

  • Well can't really be sure from the code you posted. But the exception says the the CreateAsync method needs IOrderedQueryable, but you're giving it an IQueryable.

    Try changing it to pass in the query object (which I guess should implement the IOrderedQueryable, if you're using Entity framework).

    The idea behind the PagingList (presumably) is to use it to do the paging in the database.
    What you're doing is bringing the filterted set into memory (when for-eaching through the result), and then doing doing the paging.

    The code might look something like this:

    [HttpGet]
    public async Task<IActionResult> Index(int page = 1)
    {
      var query = (from b in _context.books
                   join a in _context.authors on b.AuthorID equals a.AuthorId
                   join bg in _context.bookgroups on b.BookGroupID equals bg.BookGroupId
    
    
                   select new BookListViewModel()
                   {
                     BookId = b.BookId,
                     BookName = b.BookName,
                     BookPageCount = b.BookPageCount,
                     BookImage = b.BookImage,
                     AuthorId = b.AuthorID,
                     BookGroupId = b.BookGroupID,
                     AuthorName = a.AuthorName,
                     BookGroupName = bg.BookGroupName
                   }).AsNoTracking().OrderBy(u => u.BookId);
    
    
      ViewBag.RootPath = "/upload/thumbnailimage/";
    
      var pagedResult = await PagingList<BookListViewModel>.CreateAsync(query, 10, page);
      return View(pagedResult);
    }
    

    Hope it helps.