Edited at
ASP.NETDay 4

PagedList を使って ASP.NET MVC でページネーション

More than 3 years have passed since last update.


本記事の概要

Webアプリにおいてページ処理が必要になる場面は多いですが、自力で実装するのは大変。

Paginate機能が標準で付いているフレームワークもありますが、ASP.NET MVCには無さそうなので PagedList というライブラリを使ってみる。


PagedList (PagedList.MVC) とは

PagedList は Nuget で一番DLされてるページネイション用ライブラリ。

PagedList.MVC はHTMLヘルパー用のライブラリになりますので両方セットでインストールします。

(PagedList.MVC のほうをインストールすると PagedList も一緒にインストールされます)

https://github.com/TroyGoode/PagedList

https://www.nuget.org/packages/PagedList.Mvc


使い方(Model, Controller側)

// データベースから取得するためのIQueryable型を用意

IQueryable<Book> books = dbSet
.Where(b => b.Price < 3000)
.OrderBy(b => b.Title);

int pageNumber = 1; // ページ番号
int pageSize = 20; // 1ページに表示する件数

IPagedList<Book> bookPages = books.ToPagedList(pageNumber, pageSize); // Bookをページで取得

基本的な使い方は IQueryable型 に対して拡張メソッド ToPagedList() でページ番号とサイズを指定するだけ。

IPagedList型 は IEnumerable型 を継承してページ情報のプロパティを実装したもの。

books は ToPagedList() 実行時に、必要な件数のLIMIT句をSQLに加えた形で遅延評価されます。

さらに ToPagedList() はIQueryable型の拡張メソッドなので、前回 紹介した AutoMapper のマッピングに対してもそのまま実行できます。

IPagedList<BookViewModel> books = dbSet

.Where(b => b.Price < 3000)
.OrderBy(b => b.Title)
.ProjectTo<BookViewModel>() // AutoMapperによるBookViewModelへのマッピング
.ToPagedList(1, 20); // そのままメソッドチェーンで即時評価

このように LINQ to Entities なら 絞り込み、ソート、マッピング、ページネーション を全て繋げて一度に実行できます。便利。


使い方(View側)

表示側はこうなります


.cshtml

@using PagedList

@using PagedList.Mvc;
@model IPagedList<App.Models.Book> // IPagedList型で渡す

...

foreach(var book in Model) {
// IEnumerableを継承しているので、何も意識せずリストアップ可能
}

// ページ番号表示
@Html.PagedListPager(Model, page => Url.Action("Index", page))


Bootstrapに対応しているので、Bootstrapを導入しているとページ番号は次のような表示になります。

また、PagedListPager() の第3引数に PagedListRenderOptions を指定すれば、あらかじめ用意されたスタイルが簡単に使用できます。




最後に

2日連続で、IQueryable型のメリットと定番ライブラリを紹介させていただきました。

引き続き ASP.NET Advent Calendar 2015 をお楽しみください。