11

私は現在、永続層としてNHibernateを使用してASP.NETMVCプロジェクトを構築しています。

今のところ、いくつかの機能が実装されていますが、ローカルNHibernateセッションのみを使用します。データベースにアクセスした(読み取りまたは書き込み)各メソッドは、「using()」句を使用して独自のNHibernateセッションをインスタンス化する必要があります。

問題は、NHibernateの遅延読み込み機能を利用して、プロジェクトのパフォーマンスを向上させたいということです。

これは、ビューがレンダリングされるまで、リクエストごとにNHibernateセッションが開いていることを意味します。さらに、同時リクエストをサポートする必要があります(同時に複数のセッション)。

どうすればそれをできるだけきれいに達成できますか?

Webを少し検索して、リクエストごとのセッションのパターンについて学びました。私が見た実装のほとんどは、セッションを格納するためにある種のHttp *(HttpContextなど)オブジェクトを使用していました。また、Application_BeginRequest / Application_EndRequest関数の使用は複雑です。これは、リクエストごとに1回だけセッションをインスタンス化する場合に、HTTPリクエスト(aspxファイル、cssファイル、jsファイルなど)ごとに起動されるためです。

私が懸念しているのは、ビューまたはコントローラーがNHibernateセッション(または、より一般的にはNHibernate名前空間とコード)にアクセスできないようにすることです。つまり、コントローラーレベルでもビューレベルでもセッションを処理したくないということです。

私はいくつかのオプションを念頭に置いています。どれが一番いいと思いますか?

  • コントローラーアクションの前後にトリガーされるインターセプター(GRAILSなど)を使用します。これらは、セッション/トランザクションを開いたり閉じたりします。これはASP.NETMVCの世界で可能ですか?
  • WebコンテキストでNHibernateによって提供されるCurrentSessionContextシングルトンを使用します。このページを例として使用すると、これは非常に有望だと思いますが、それでもコントローラーレベルでのフィルターが必要です。
  • HttpContext.Current.Itemsを使用して、リクエストセッションを保存します。これは、Global.asax.csの数行のコードと相まって、リクエストレベルでのセッションを簡単に提供できます。ただし、これはNHibernateと私のビュー(HttpContext)の間に依存関係が注入されることを意味します。

どうもありがとうございます!

4

5 に答える 5

13

皆さん、数日間の作業の後、最終的に HttpContext.Current.Items を使用してセッションをロードすることにしました。

それはうまくいきます!

これが私がやった方法です

import System.Web
class SessionManager {
    public static ISession GetSession()
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session == null) {
            session = ...; // Create session, like SessionFactory.createSession()...
            HttpContext.Current.Items.Add("NHibernateSession", session);
        }
        return session;
    }

    public static void CloseSession()
    {
        var session = HttpContext.Current.Items["NHibernateSession"];
        if (session != null) {
            if (session.IsOpen) {
                session.close();
            }
            HttpContext.Current.Items.Remove("NHibernateSession");
        }
    }
}

このクラスが提供する静的メソッドを使用することで、現在の HttpContext (現在の Web 要求) に関連付けられたセッション (たとえば、コントローラー内) を取得できます。リクエストが完了したときに CloseSession() メソッドを呼び出すには、別のコード スニペットが必要です。

Global.asax.cs で:

protected void Application_EndRequest(object sender, EventArgs args)
{
    NHibernateSessionManager.CloseSession();
}

Application_EndRequest イベントは、セッションが完了すると自動的に呼び出されるため、セッションを適切に閉じて破棄することができます。そうしないと、すべてのコントローラーでこれを行う必要があるため、これは便利です!

于 2010-01-19T06:19:45.747 に答える
2

IoC と共に DI を使用します。ほとんどの IoC には、リクエストごとのインスタンス化動作が付属しています。

于 2010-01-12T20:22:04.353 に答える
2

私の「解決策」には、Unity を使用して、コントローラーでリクエストごとにセッションを挿入することが含まれます。

http://letsfollowtheyellowbrickroad.blogspot.com/2010/05/nhibernate-sessions-in-aspnet-mvc.html

于 2010-05-16T20:05:03.603 に答える
1

NHibernate のセッションとトランザクションを管理できるアクション フィルターを追加できます。(これは、アクション レベルまたはコントローラー レベルで実行できます。) 以下にその例を示します。

http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx

于 2010-01-12T02:55:38.063 に答える
1

S#arp Architectureを見てください。これは、ASP.NET MVC および NHibernate にとって非常に優れたアーキテクチャです。

于 2010-01-12T01:59:06.433 に答える