2009-07-08 11 views
0

私はちょうどNHibernateの使用を開始しました。私は正しく解決する方法がわからないいくつかの問題があります。NHibernateセッション - Windowsアプリケーションでセッションを処理する一般的な方法は何ですか?

私は、CUDといくつかの検索方法を含む汎用リポジトリの作成を始めました。これらのメソッドはそれぞれ、DB操作中に個別のセッション(および必要に応じてトランザクション)を開きます。これを行うときの問題は、関連するコレクション/オブジェクトの遅延読み込みを利用できないことです。

ほとんどすべてのエンティティリレーションは、フルーエントマッピングで.Not.LazyLoad()であるため、特定のタイプのすべてのエンティティのリストを要求すると、データベース全体がロードされます。私が間違っている場合

は、これを避けるために行うのが最も一般的である何NHibernateは:)

に来るとき、私はまだ完全な初心者だ「原因、私は正しいですか?プログラムが実行されている間、生きているグローバルな静的セッションが1つありますか?何をすべきですか?


リポジトリコードの一部:

public T GetById(int id) 
{ 
    using (var session = NHibernateHelper.OpenSession()) 
    { 
     return session.Get<T>(id); 
    } 
} 

あなたの質問は、実際のキャッシュと再利用をobjectに沸く人

var person = m_PersonRepository.GetById(1); // works fine 

var contactInfo = person.ContactInfo; // Throws exception with message: 

// failed to lazily initialize a collection, no session or session was closed 

答えて

3

を取得するには、リポジトリを使用しました。 1つのセッションからFooオブジェクトをロードすると、それを保持したまま、遅い時点でBarプロパティを読み込みませんか?

各ISessionインスタンスは作業単位を表すように設計されており、その作業単位内で複数のオブジェクトを取得し、単一のデータベース・ヒットのみを持つ第1レベルのキャッシュが付属しています。これはスレッドセーフではないため、WinFormsアプリケーションで静的オブジェクトとして使用する必要はありません。

ロードされたセッションが破棄されたときにオブジェクトを使用する場合は、Session.SaveOrUpdate(オブジェクト)またはSession.Update(オブジェクト)を使用して新しいセッションに関連付ける必要があります。

このすべてはchapter 10 of the Hibernate documentationで説明されています。

これが非効率的な場合は、第2レベルのキャッシュを調べます。これはISessionFactoryレベルで提供されています。セッションファクトリは静的である可能性があります。セカンドレベルのキャッシュを有効にすると、データの大半をメモリ内にキャッシュする効果があります。セカンドレベルのキャッシュは、データを更新している基本サービスがない場合にのみ適切です。すべてのデータベースの更新がNHibernateを経由する場合、安全です。あなたではなく、作業の単位よりも、得る単一のデータベースのためにそれを使用している - コードの光の中で

編集はあなたのセッション使用が間違っレベルである

掲載しました。この場合、使用するセッションにはGetByIdメソッドが必要であり、セッションインスタンスはより高いレベルで管理する必要があります。代わりに、ご希望の場合はPersonRepositoryクラスでセッションを管理し、各作業単位ごとにこのタイプのオブジェクトをインスタンス化して処分する必要があります。

public T GetById(int id) 
{ 
    return m_session.Get<T>(id); 
} 

using (var repository = new PersonRepository()) 
{ 
    var person = repository.GetById(1); 
    var contactInfo = person.ContactInfo; 
} // make sure the repository Dispose method disposes the session. 

遅延ロードにコレクションを使用するセッションがなくなったので、あなたが取得しているエラーメッセージはありません - あなたはすでにそれを配置されました。

+0

あなたの答えをありがとう。ドキュメントの章を読んだことがありますが、2番目の文で何を意味するのかはまだ分かりません。遅延読み込みプロパティにアクセスする必要がある場合は、セッションを保持する必要があることを意味しますか?質問に自分のリポジトリコードを追加します。 – l3dx

+0

確かめてください。質問にいくつかの文脈を追加してください。私は答えにもっと具体的に取り上げます。 –

+0

ニース、ありがとう! +1私のリポジトリをリファクタリングします:)私の理解では、セッション/ dbのものは実際のアプリケーションから "階層化されています"ので、リポジトリから削除すると、どこに置くのでしょうか? – l3dx

関連する問題