NHibernate - 非法访问加载集合

时间:2011-04-01 11:36:55

标签: nhibernate hbm

我有两个实体,即客户和帐户。客户有很多帐户。

我对客户的映射是:

<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();”虽然成功了。

任何人都有任何想法在这里发生了什么?

3 个答案:

答案 0 :(得分:4)

我认为这很简单:您不再拥有与该实体关联的开放ISession。并且,我认为这是因为将会话管理(打开/关闭会话)作为对存储库的责任,这是错误的。

答案 1 :(得分:0)

这里的问题实际上是'ISession'被关闭了,虽然这并不是因为它被如前所述的个别存储库处理。

问题的原因是我将我的UnitOfWork(ISession)声明在我的业务方法范围之外 - PlaceOrder()。例如:

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);
    ....                

最终,这个问题是由于缺乏对工作单元概念的理解。如果我的理解现在是正确的,那么每个业务方法(例如上面的PlaceOrder)都是一个新事务,因此需要在开始时打开ISession并在结束时关闭。我在方法范围之外宣称ISession认为它只需要声明一次。

答案 2 :(得分:0)

我也遇到了这个错误 - 但我只是在断点时发现了它。我的错误是由DebuggerDisplay属性试图显示懒惰加载的属性引起的。