2012-04-17 13 views
1

私は問題が発生しています。 MVC3ビューからNHibernateエンティティの遅延ロードされたプロパティにアクセスしようとすると、「セッションなし」LazyInitializationExceptionがスローされます。これは先週、私たちの上で起き始めただけですが、私たちは問題を絞り込むことができませんでした。しかし、単純な解決策があるようには見えません。MVC3ビューで遅れてロードされたNHibernateエンティティ

ノート:スタックトレースの

  • 例:http://textsnip.com/613608
  • 私たちは、私たちのプロジェクトの任意の場所に廃棄し(または使用してセッションをラップ)しないでください。 ObjectFactoryはそれを処理させます。
  • は、回帰テスト(WatFNでSpecFlow)を実行するとTeamCityテスト環境で発生します。私たちの誰も私たちの開発マシンで問題を再現することはできません。
  • これも一貫して発生しません。失敗したテストは通常​​同じテストですが、常に失敗するわけではありません。同じビューの一部に当たるページにアクセスする他のテストは失敗しません。
  • 失敗したテストでは、非コレクションより初期化された遅延読み込み負荷の方が重いと思われますが、どちらも起こります。
  • 多くのテーブルモデルの相互依存性のために可能なときはいつでも、エンティティを熱心に読み込むほうがよいとわかっていますが、現時点で実現可能なものではありません。

ここでは何が欠けていますか?

+0

エンティティを公開し、条件/クエリをnhibernateできますか? – Mariusz

+0

あなたのテストでは、どのようにISessionを管理していますか? – dotjoe

答えて

0

ビュー内のオブジェクトモデルに直接バインドしていますか?バインドをドメインオブジェクトに直接表示するという点で、あなたの問題のように思えます。ドメインオブジェクトは遅延コレクションを持っているので、Nhibernateセッションを必要とするオンデマンドでコレクション要素をロードしようとしています。

コントローラメソッドで完全なビューモデルを構築する必要があります。

あなたが持っているビューごとにビューモデルを作成することをお勧めします。次に、NHibernateに問い合わせるときは、モデルに直接投影するか、Automapperを使ってオブジェクトモデルをビューモデルに変換します。直接投影に関する素晴らしい点は、nhibernateによるクエリは、必要な列のみを選択するため、より効率的であるということです。

この記事も参照してください。 http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

ビューモデルのベストプラクティスのセットです。

+0

私たちは実際のエンティティをビュー内で使用しようとするとノー・ノーと見なされますが、現時点ではそれを変更する立場にはありません。また、この問題は最近数ヶ月間うまくいきました。私たちはNHibernateセッションが必要であることを知っています。そのため、ObjectFactoryは要求ごとに作成しています。そのため、モデルがビューで使用されている間はまだ生きているはずです。 – rossisdead

1

あなたのエンティティの読み込みパターンはビュー内でオープンセッションと呼ばれ、反パターンとみなされます。このパターンの短所についてもっと教えてくださいherehere

プリフェッチされたデータを持つビューモデルを使用することをお勧めします。しかし、あなたがそれを行うことができない場合は、linhを使用してモデルデータをプリフェッチして、拡張拡張をnhibernateすることができます。オープンソースライブラリITDT.Sentiaがあります。これは、入力拡張機能を提供しています。また、Googleで「nhibernate expand」を検索することもできます。低レベルのものについては、nhibernate fetching strategiesをご覧ください。

たとえば、ITDTを使用します。センティアライブラリとなる次のモデルは:私は推測することができますDEV-環境では異なる動作については

IList<User> users = userRepository 
    .GetAll() 
    .Where(u => /*some constraints*/) 
// here you are telling nhibernate to make a join and eger load what you need 
    .Expand(u => u.Company) 
    .ToList(); 

public class User : BaseEntity 
{ 
    public virtual string Email { get; set; } 
    public virtual Company Company { get; set; } 
} 

public class Company : BaseEntity 
{ 
    public virtual string Name { get; set; } 
} 

とユーザーを取得した後、会社の実体の遅延ロードを想定して、あなたのような何かを行うことができますどういうわけか他の設定ファイルを使用しています、おそらく、異なるdebug/release web.configsがありますか?

関連する問題