8

基本的な Get/Save/Delete メソッドを定義するリポジトリ クラスがあります。これらの中で、NHibernate を使用してビジネス エンティティの作業を行います。例えば:

Public Class SecurityRepositoryNHibImpl : Implements ISecurityRepository
    Public Function GetUser(ByVal UUID As System.Guid) As Entities.User Implements ISecurityRepository.GetUser
        Dim eUser As Entities.User
        Using session As ISession = NHibernateHelper.OpenSession()
            eUser = session.Get(Of Entities.User)(UUID)
        End Using
        Return eUser
    End Function
End Class

ただし、私の User クラスには、理想的には遅延ロードしたいいくつかのプロパティと他のオブジェクトのコレクションがあります。しかし、もちろん、ISession はリポジトリ内で作成および破棄されるため、それ以外に、これらのプロパティにアクセスしようとすると、「プロキシを初期化できませんでした - セッションがありません」というエラーが発生します。

リポジトリを使用するときに遅延読み込みを無効にする唯一のオプションはありますか? それとも、どうにかしてセッションをビジネス層のスコープに入れることは可能ですか (または単にばかげていますか)?

私はリポジトリ モデルが好きで、NHibernate は私の上で成長しています (それを機能させようとして多くの最初のフラストレーションの後)。

私はNHibernateとリポジトリモデル全般にかなり慣れていないので(仕事ではまだ主にVB6を使用しています!)、ばかげた質問かもしれませんがご容赦ください。ありがとう。


@mookid: ありがとうございます。とても役に立ちますが、もう少し開いたままにしておくかもしれません。これは WCF Web サービスのバックエンドであり、すべての機能が呼び出しごとのコンテキストになるため、呼び出しごとのセッション ライフは良好です。そのようなことをビジネス層で機能させる方法がわからないだけで、理想的には、ビジネスオブジェクトが NHibernate クラスと直接やり取りする必要はありません。NHibernate セッションのある種のラッパーが、少なくともそれを抽象化していると思います... うーん、少なくとも正しい軌道に乗せてくれました。


ここでのキーワードは "Unit of Work" であると思われます。NHibernate に関連する Web 上には、大量のリソースが存在します。特に、Rhino Commons での Ayende の実装と、彼の App Architecture Web キャスト(Hibernating Rhinos の No. 9) を探してください。非常に有益です。ビジネス層に「Unit of Work」を配置することは懸念を混同していたので、最初は混乱しましたが、すぐに修正されました。

4

1 に答える 1

12

ISession を作成し、そのように明示的にリポジトリ内に配置することは、小さくて非常に単純なプロジェクトでは問題ありませんが、ご存知のように、NHibernate がサポートするいくつかの優れた機能を使用したい場合には不十分です。

おそらく、セッションのライフスタイルをリポジトリの外部の何かによって制御できるようにする必要があります。たとえば、ASP.NET Web アプリケーションを実行している場合、現在のリクエストでセッションを保存したい場合があります (HttpContext.Current.Items正しく思い出せば)。 Web 要求をコミットし、要求の最後に破棄します (例外が発生した場合はロールバックします)。

ASP.NET アプリケーションでセッションのライフスタイルを制御する最善の方法はわかりませんが、各要求の最初と最後にコードを呼び出す何らかの方法が必要です。OnActionExecutingASP.NET MVC では、メソッドとメソッドをオーバーライドしたベース コントローラーからすべてのコントローラーを派生させることで、簡単に実現できますOnActionExecuted

于 2009-03-16T14:38:01.727 に答える