4

Winforms と WPF で NHibernate を使用して数年経った今でも、非常に重要なポイントを 1 つ見落としているように思われます。このコード スニペットを実行すると明らかになりすぎました。

 ISessionFactory sf = Fluently.Configure()
                              .Database(MsSqlConfiguration.MsSql2008
                                .ConnectionString(c => c.Is(connectionString)))
                              .Mappings(x => x.FluentMappings
                                .AddFromAssemblyOf<MyClass>())
                              .BuildSessionFactory();

 for (int i = 0; i < 100; i++)
 {
     new Task(()=>
     {
         Console.WriteLine("{0}, {1}",
           i, 
           sf.OpenSession().QueryOver<MyClass>().List().Count);
     }).Start();
 }

これにより、多くの負荷がかかると思います。

正直なところ、セッション処理について読んだ記憶があるのは、原子セッションを宣言する Unit Of Work の実装だけです。それで、パターンを見て、いくつかの懸念/質問があります。

  • 遅延読み込みはどのように図に収まりますか? 1 つのセッションを使用してデータをロードしてから閉じると、遅延ロードが機能しません。したがって、基本的に、作業単位はセッションを閉じたり破棄したりできません。つまり、セッションは無限に大きくなります。

  • セッションには次のような機能がありますIsDirty。オブジェクトの読み込みと保存が別々のセッションで行われる場合、これをどのように利用できますか?

編集: Oren Eini は、彼の初期の記事で問題とまったく同じことを述べています。そこで彼は、MicroManaging (=> use and immediate Dispose) が LazyLoading や ChangeTracking などの NH 機能を遮断すると述べています。ただし、UnitOfWork は Session MicroManagement パターンのようです。では、最もクリーンなソリューションは何ですか? 自分で変更を追跡し、MicroManagement を使用していますか? モノリシック セッション (= 設計による Memleak)? Oren の例とは異なり、セッションの有効期間を制限できるサブダイアログが多くない場合はどうでしょうか?

4

1 に答える 1

4

遅延読み込みはどのように図に収まりますか?

遅延読み込みは、1 つのセッションの図に収まります。オブジェクトが読み込まれると、遅延読み込みにより、オブジェクト プロパティがデータベースから既に読み込まれているかどうかを知る必要なく、すべてのオブジェクト グラフを積極的に読み込むことなく、オブジェクトのグラフをトラバースできます。

完璧に見えますが、「n + 1 select」などの問題があります

1 つのセッションを使用してデータをロードしてから閉じると、遅延ロードが機能しません。

db から同じオブジェクトをロードする別のセッションは、前のセッションで遅延ロードされたプロパティの恩恵を受けません。

したがって、基本的に、作業単位はセッションを閉じたり破棄したりできません。つまり、セッションは無限に大きくなります。

私はこれを理解しているかどうかわかりません。セッションは作業単位だと思います。

セッションには IsDirty のような機能があります。オブジェクトの読み込みと保存が別々のセッションで行われる場合、これをどのように利用できますか?

読み込みと保存は別々のセッションで行うべきではありません。それが IsDirty プロパティのポイントだと思います。

これにより、NH 処理に関する多くのヒントが得られる可能性があります: https://softwareengineering.stackexchange.com/q/100534

これが役立つことを願っています

編集:2番目の質問について。通常の Web シナリオは次のようになります。

  1. NH セッションを開く
  2. NH エンティティをロードする
  3. UIに表示するためにPOCOでNHエンティティのプロパティを転送します(もちろん、IDを追跡します)
  4. NH セッションを閉じる
  5. 後で (ユーザーがいくつかの変更を行い、[保存] ボタンを押します)、NH セッションを開きます。
  6. 対応する NH エンティティをロードします (ID によって)
  7. 新しい POCO フィールドに従って NH エンティティを更新する
  8. DB の変更を永続化する
  9. NH セッションを閉じる

1、2、および 4 は、最初の作業単位の一部です。5、6、7、8、および 9 は、2 番目の作業単位の一部です。

于 2013-02-22T09:41:08.020 に答える