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”已关闭,尽管这并不是因为它是由先前建议的单个存储库处理的。

问题的原因是我声明了我的 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,认为它只需要声明一次。

于 2011-04-06T08:34:46.307 回答