1

シナリオ:料理のレシピを管理する ASP.NET MVC アプリケーションを構築しました。FluentNHibernate を使用して、次のテーブルのデータにアクセスしています。

  1. ユーザー
  2. カテゴリー
  3. レシピ
  4. RecipeCategories (多対多のジャンクション テーブル)
  5. UserBookmarkedRecipes (多対多のジャンクション テーブル)
  6. UserCookedRecipes (多対多のジャンクション テーブル)

質問: NHibernate に上記のすべてのテーブルからすべてのデータをロードし、それをメモリまたは NHibernate のキャッシュに格納して、追加のデータベース要求が発生しないようにする方法はありますか?


質問の背後にある動機:さまざまな多対多の関係が問題を引き起こし、その最適化によって大きなメリットが得られます。

データに関する注意:全体のデータ量は非常に少ないです。現時点では、100 未満のレシピについて話しています。

4

1 に答える 1

2

すべてをプリロードするのではなく、一度ロードしてから、アクセス時に保持することをお勧めします。

NHibernate は 2 つの異なるキャッシュを維持し、基盤となるデータ ストアとの同期を適切に維持します。デフォルトでは、セッションごとに「一次」キャッシュと呼ばれるものを使用しますが、それはあなたが望んでいるものではないと思います。キャッシングに関する nhibernate faq ページで違いについて読むことができます

2 番目のレベルのキャッシュが必要だと思います (これはアプリ全体で利用できます)。NHContribからキャッシュ プロバイダーを取得する必要があります(NHibernate のバージョンと一致するバージョンをダウンロードします)。SysCache2 プロバイダーは、アプリケーションがデータベースに書き込む唯一のものである限り、おそらくシナリオに最も簡単に設定できます。他のプロセスが書き込みを行う場合、同期を維持したい場合は、すべてが仲介として同じキャッシュを使用していることを確認する必要があります。

2 番目のレベルのキャッシュは、必要に応じて設定できるタイムアウトで構成されます。無限にできるとは思わないでください。ただし、必要に応じて長期間に設定できます (おそらく、時々 DB に戻るのは悪い考えではありません)。前もってすべてをプリロードしたい場合は、global.asax の Application_Start メソッドからすべてのエンティティにアクセスできますが、これは必須ではありません。

キャッシュを使用するには、セッション ファクトリを構成する必要があります。セッションファクトリを流暢に構成するときに .Cache(...) メソッドを呼び出します。これは比較的自明です。

また、エンティティ マッピングと関係マッピングの両方で Cache.ReadWrite() を設定する必要があります。これは、規則に従って行うか、流暢なマッピングで Cache.ReadWrite() を呼び出すことによって行うことができます。

何かのようなもの:

public class RecipeMap : ClassMap<Recipe> {
    public RecipeMap () {
        Cache.ReadWrite();
        Id(x => x.Id);
        HasManyToMany(x => x.Ingredients).Cache.ReadWrite();
    }
}

マッピングの Cache 呼び出しでは、ReadOnly など、必要なものを指定できます。NonStrictReadWrite は興味深いものです。パフォーマンスを大幅に向上させることができますが、キャッシュから古いデータを読み取るリスクが高くなります。

于 2011-11-12T03:04:50.043 に答える