2

顧客とアカウントの2つのエンティティがあります。顧客は多くのアカウントを持っています。

顧客のマッピングは次のとおりです。

<bag cascade="all" name="Accounts" table ="Accounts" mutable="true" inverse="true">
  <key>
    <column name="Customer_Id" />
  </key>
  <one-to-many class="Account, POCOEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bag>

アカウントのマッピングは次のとおりです。

<many-to-one cascade="all" class="Customer, POCOEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Customer">
  <column name="Customer_Id" />
</many-to-one>

私のアプリケーションでは、IDに基づいて顧客を取得します。

var customer = _customerRepository.GetById(custID);

次に、次の方法で顧客の最初のアカウントを取得しようとします。

Account account = customer.Accounts.FirstOrDefault();

次に、次の例外が発生します:「NHibernate.LazyInitializationException:ロードコレクションへの不正アクセス」

ここに掲載されているこの問題に対して他の解決策を試しましたが、何も機能していません。本当に奇妙なのは、アカウントにアクセスしようとする直前に次のコードを挿入すると、すべてが機能することです。

var acc = from a in _accountRepository.GetAll()
                  where a.Customer.Equals(customer)
                  select a;

前のコードで行ったのは、使用すらしない変数を作成することだけです。どういうわけか、「Account account = customer.Accounts.FirstOrDefault();」というステートメントが発生します。しかし成功するために。

誰かがここで何が起こっているのか考えがありますか?

4

3 に答える 3

4

非常に単純だと思います。エンティティに関連付けられた開いている ISession がなくなりました。そして、これは、セッション管理 (セッションを開く/閉じる) をリポジトリへの責任として任せているためだと思いますが、それは間違っています。

于 2011-04-01T11:45:17.620 に答える
0

このエラーも発生していましたが、ブレークポイントでのみ気づきました。私のエラーは、遅延ロードされたプロパティを表示しようとする DebuggerDisplay 属性を持っていることが原因でした。

于 2011-12-16T13:59:38.707 に答える
0

ここでの問題は、実際には「ISession」が閉じられたことにありましたが、これは以前に示唆されたように個々のリポジトリによって処理されたためではありません。

この問題の原因は、ビジネス メソッド PlaceOrder() の範囲外で UnitOfWork (ISession) を宣言したことです。例えば:

ISession myUnitOfWork = new ISession();


public void PlaceOrder()
{

    var myRepository = new IRepository<Customer>(myUnitOfWork);
    ....
    ....
    Commit();
}

そのため、PlaceOrder() メソッドへの最初の呼び出しは問題ありませんでしたが、追加の呼び出しで ISession が閉じられたため、「コレクションの読み込みへの不正なアクセス」メッセージが表示されました。解決策は、PlaceOrder() メソッド内で ISession を宣言することでした。

public void PlaceOrder()
{
    ISession myUnitOfWork = new ISession();
    var myRepository = new IRepository<Customer>(myUnitOfWork);
    ....                

最終的に、この問題は、Unit of Work の概念が理解されていないことが原因でした。私の理解が正しければ、各ビジネス メソッド (上記の PlaceOrder など) は新しいトランザクションであるため、最初に ISession を開き、最後に閉じる必要があります。私は、一度だけ宣言する必要があると考えて、メソッドの範囲外で ISession を宣言していました。

于 2011-04-06T08:34:46.307 に答える