MVCでのページングに関する多くの記事と回答を読みました。(PagedListを使用して)ページングを使用して検索結果を作成することができましたが、別のものが必要になりました。ジャンルのリストがあり、ジャンルに基づいて、そのジャンルのすべてのアルバムを閲覧したいと思います。URLはHome/Browse / 1(ジャンルのID)です。すでにパラメータ(genreid)が含まれているため、この結果をページングするにはどうすればよいですか?ありがとう
2 に答える
ページ付けの方法を本当に理解したい場合は、他の人のPagedList
抽象化に頼るのではなく、独自のカスタムページングロジックを作成することをお勧めします。
結果をページ分割する必要がある場合は、データベースに送信されるクエリ全体の他の2つの側面(フィルタリングと並べ替え)も含める必要があります。
その理由は、ページングと組み合わせて並べ替えとフィルタリングの両方を適用しない限り、正しい結果を計算できないためです。
たとえば、100行のテーブルがあり、ページごとに10行を表示したいとします。AZでソートされた最初の10行は、ZAでソートされた最初の10行とは異なります。したがって、テーブルをページ分割する前に、テーブルを並べ替える必要があります。
あなたの質問はフィルタリングと関係があります-あなたは特定のジャンルにないすべてのアルバムを除外したいと思います。繰り返しますが、これは、フィルタリングされた結果をページ分割する前にフィルタリングを適用する必要があることを意味します。
最終的に、コントローラーは結果を取得するためにデータベースにアクセスする必要があります。フィルタリングおよびソートされたクエリをデータベースに送信し、サブセットのみを切り取ってユーザーにページ付けを表示することで、ページ付けを行うことができます。しかし、あなたができるからといって、あなたがそうすべきだという意味ではありません。理想的には、フィルタリング、並べ替え、ページ付けを適用するdb 1クエリを送信して、必要なページセクションを正確に返します。
次のようなクエリでこれを実行できるはずです。
// assuming pageNumber is Nullable<int>, and is passed as action method argument
pageNumber = pageNumber ?? 1
var pageSize = 10;
var pageIndex = pageNumber.HasValue ? pageNumber.Value - 1 : 0;
var results = context.Albums
.Where(a => a.GenreId == genreId) // filtering
.OrderBy(a => a.GenreId) // sorting
.Skip(pageSize * pageIndex) // skip this many rows (pagination start at)
.Take(pageSize) // then give me this many rows (pagination chunk)
.ToList() // execute the query against the database
;
return view(results);
ビューのモデルタイプは次のようになります。
@model IEnumerable<Album>
PagedListとMVCを使用することで、pageNumberパラメーターをコントローラー/アクションメソッドに送信する方法を既に知っていると思います。フィルタリングURL(Home / Browse / 1)の場合、フィルタリングパラメーターはすでにアクションメソッドに渡されています。
ユーザーが結果を並べ替えることも許可することにした場合は、並べ替え情報をactionメソッドパラメーターに渡す必要もあります。上記のコードは、データベース内の自然順序付けを前提としています(通常はAlbumIdによるものです)。
同じことがpageSizeにも当てはまります。クエリの一部(並べ替え、フィルタリング、pageSize、pageNumber)をユーザーがカスタマイズできるようにする場合は、これらの値を引数としてactionメソッドに渡す必要があります。それ以外の場合、コントローラーは上記の例のようにコンパイルされた値を使用する必要があります。
PagedListの作成者はこちら。あなたはあなたがそう求めていることをすることができます:
http://localhost:1234/home/browse/1?page=2
public class HomeController : Controller
{
public object Browse(int genreId, int? page)
{
// the *page* variable is bound to the querystring value, not the route
return View(Genres.All().ToPagedList(page ?? 1, 10);
}
}