2011-01-26 30 views
2

UIレイヤで遅延ロードを使用するとセッションの問題が発生しました。nhibernate遅延ロード

public List<Visites> GetVisitesClientQuery(string idClient) 
{ 
    using (ISession session = Repository.TSession()) 
    { 
     var results = (from v in session.Query<Visites>() 
         where v.Clients.Idclient == idClient 
         select v); 

     return results.ToList<Visites>(); 
    } 
} 

(DAO層における)コードの

私の作品は、私は、UI層にそれを呼び出す:

var visites = VisiteManager.Instance.GetVisitesClientQuery(lstClients.SelectedValue.ToString()); 
foreach (Visites v in visites) 
{ 
    foreach (Factures f in v.Factures) 
    { 
     ... 
    } 
} 

v.Facturesコレクションです。

私はそれを使用して呼び出すと(セッションが開かれています)、この場合は動作しません。このエラーがあります。

Initializing[NHibernateTest.BusinessObjects.Visites#036000007935]- 
failed to lazily initialize a collection of role: 
NHibernateTest.BusinessObjects.Visites.Factures, no session or session was closed 

UIレイヤーでレイジーローディングコールを処理することはできますか?

答えて

4

ここでの問題は、あなたのリポジトリ(DAO層)内でセッション管理を処理することです。これは良い考えではありません。

NHibernateのISessionの実装は、 'Unit Of Work'を表します。作業単位は、この概念をうまく使えるようにするために、「ユースケース」の「コンテキスト」を知る必要があります。

しかし、リポジトリには、リポジトリを使用するユースケースの「コンテキスト」という概念はありません。 したがって、あなたのDAO層ではなく、いつセッションを開くかを決定する必要がありますが、これはアプリケーション層を持たない場合はアプリケーション層(またはアプリケーション層がない場合はUI層)です。あなたの文脈を知っている層になります。

そうすることで、実際にセッションをUnitofWorkとして効果的に使用できます。エンティティを保存するには、そのエンティティをロードするために使用したセッションと同じセッションを使用してエンティティを保存する必要があります。 (そうでなければ、エンティティをセッションに「ロック」する必要があります)。 次に、遅延読み込みの問題も解決します。 :)

+0

しかし、私は私のビュー層でnhibernate関数を使うべきではないと思った? ...関連性の高いリンクhttp://stackoverflow.com/questions/1379500/nhibernate-removes-dalが見つかりました。私はすべての層でかなり失われています... –

+0

あなたのリポジトリ実装はあなたのDALです。ただし、これはあなたのDALがあなたのセッションを作成することを意味するものではありません。 Sessionをリポジトリに渡すことができます。 –

1

session.Query()。Fetch(x => x.Factures)で使用することがわかっているコレクションを熱心に読み込む必要があります。

これはFacturesのすべてのVisitesを読み込みます。