4

これに似たシナリオがあります: nHibernate Session Per Request を使用する Asp.NET MVC 4 Web サイト。セッションは、Ninject を使用して、Get メソッドと Save メソッドを使用してリポジトリに挿入されます。

Session Per Request について説明し、それが Web アプリケーションで行う方法であると述べている記事がたくさんあります。

しかし、次のようなロジックの実装に問題があります。

Read Data From Database
Alter Entity information
Save to Database
Read another entity
Alter entity
Save ... but an EXCEPTION OCCURS

ユーザーにメッセージを表示してビューを表示したい。しかし、結果の Web ページも更新する必要があるため、データベースからいくつかの情報を読み取る必要もあります。

nHibernate のドキュメントによると、例外が発生したセッションは破棄する必要があります。ドキュメントはこちら

しかし、ここで進める最善の方法に関する記事が見つかりません。

この状況に最適なアプローチは何ですか? 新しいセッションをリポジトリ オブジェクトに挿入する必要がありますか?

ありがとう。

4

1 に答える 1

4

元のセッションのSessionFactoryプロパティから新しいセッションを作成できます。元のセッションオブジェクトにアクセスするには、リポジトリクラスで公開するか、コントローラーに挿入します。次に、新しいセッションで新しいリポジトリを作成できます。

これは、一意のキー違反が発生すると予想されるアクションの一部で行い、モデルにルックアップデータを再ロードする必要があります。次に例を示します。

    public ActionResult Create(MeasuresEditView model)
    {
        if (ModelState.IsValid)
        {
            using (var txn = _session.BeginTransaction())
            {
                try
                {
                    var measure = new Measure { Code = model.Code };
                    _session.Save(measure);
                    txn.Commit();
                    return RedirectToAction("Index");
                }
                catch (UniqueKeyException)
                {
                    txn.Rollback();
                    var msg = string.Format("A measure with the code '{0}' already exists, please enter a different code or cancel.", model.Code);
                    ModelState.AddModelError("Code", msg);
                }
                catch (Exception ex)
                {
                    if (txn.IsActive)
                    {
                        txn.Rollback();
                    }
                    log.Error("Create", ex);
                    throw;
                }
            }
        }
        // have to rebuild selectlist on post in new txn in case it was rolled back
        using (var session = _session.SessionFactory.OpenSession())
        using (var txn = session.BeginTransaction())
        {
            SetProductGroupSelectList(session, model, manualId);
            txn.Commit();
        }
        return View(model);
    }
于 2012-12-28T20:07:43.650 に答える