NHibernateでのページング
-
05-07-2019 - |
質問
BlogEntries(BlogEntry型のオブジェクトを含む)というプロパティを持つBlogというクラスのドメインモデルがあるとします。 2つのテーブル" Blog"を持つデータベースモデルがある場合、および「BlogEntry」を使用して、1つのブログに1000個のブログエントリがあることは不可能ではありません。ブログをWebサイトに表示する場合、一度に20のブログエントリのみを表示したいので、何らかのページングを使用する必要があります。私は明らかに、常に1000件のレコードをDBから取得したくないのです。
どうすればそれができますか? BlogEntriesプロパティはBlogドメインオブジェクトにあるべきでしょうか、それともリポジトリにあるべきでしょうか?ブログエントリを追加したり、既存のエントリのページングされた結果を取得したりする可能性が引き続きあります。 NHibernateマッピングはどのようになりますか?
Blog / BlogEntryの例は単なる例であり、Customer / Orderの例やその他のマスター/詳細のシナリオにもなり得ます。
教えてください!
解決
BlogEntryを独自のAggregateルートにし、独自のリポジトリにします。特定のBlogIDを持つすべてのBlogEntryのBlogEntryリポジトリーを照会することにより、特定のBlogのBlogEntryインスタンスを取得します。リポジトリを実装するためのいくつかの異なる戦略があるため、それ以上のリポジトリに関する詳細を提供することはできません(1つの汎用リポジトリと多数の個別のファインダメソッドと複雑な仕様オブジェクトを取得するメソッドなど)。リポジトリのfinderメソッドはページングをサポートする必要があります。
public class Blog
{
public int ID {get;set;}
// other stuff
}
public class BlogEntry
{
public int ID {get;set;}
public int BlogID {get;set;}
}
public class BlogEntryRepository
{
public IEnumerable<BlogEntry> FindByBlogID(
int blogID, int pageIndex, int pageSize)
{
// implementation
}
}
別の方法として、(Aggregateルートとしてモデル化されたBlogEntryを使用して)BlogEntryIDのコレクションをBlogクラスに追加することもできます。 Blogインスタンスを取得するときに読み込むデータがはるかに少ないため、BlogクラスにBlogEntryインスタンス自体を保持するよりも優れています。これらのIDを使用して、それらのサブセットを選択し、IDのコレクションを受け入れるBlogEntryリポジトリメソッドに渡すことができます。言い換えれば、ページングをサポートするためにドメインにもう少しロジックがあり、リポジトリにはより一般的なゲッターがあります。
public class Blog
{
public int ID {get;set;}
public IEnumerable<int> BlogEntryIDs {get;set;}
// other stuff
}
public class BlogEntry
{
public int ID {get;set;}
public int BlogID {get;set;}
}
public class BlogEntryRepository
{
public IEnumerable<BlogEntry> Get(IEnumerable<int> blogEntryIDs)
{
// implementation
}
}
このアプローチの使用法は次のようになります
// get the second page
var entries =
blogEntryRepo.Get(blog.BlogEntryIDs).Skip(1 * PAGE_SIZE).Take(PAGE_SIZE);
データベースでは、ブログエントリごとに1行、複数の行を返します。 (複数の結果セットを返して、1回のデータベースラウンドトリップですべての関連テーブルからすべての行を取得することも好みます。また、SQL 2005のROW_VERSION関数を使用してデータベースページングを有効にします。)
私は通常、2番目の方法を好みますが、通常の使用法では、ブログに関連付けられているBlogEntryインスタンスの数が非常に多い(例:数千を超える)場合を除きます。 intの配列が多すぎると、パフォーマンスとメモリに注意することになります。
他のヒント
ページリストを取得するには、独自のリポジトリのブログエントリにアクセスする必要があります。
編集:なぜ投票するのですか?これは間違っていますか?
ブログエントリのコレクションには、 BatchSizeを使用できます。 属性。データベースからすべてのコレクションを選択するのではなく、必要な値のみを選択できます。