2011-04-01 44 views
2

我有两个实体,客户和帐户。客户拥有多个帐户。NHibernate - 非法访问加载集合

我对客户的映射是:

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

所有我已经在前面的代码做的是创造,我甚至不使用的变量。不知何故,它会导致声明“帐户帐户= customer.Accounts.FirstOrDefault();”尽管如此。

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

+0

您是否尝试删除“可变”属性? – mathieu 2011-04-01 12:11:33

回答

4

我认为这很简单:你不再有一个开放的ISession与实体关联。而且,我认为这是因为将会话管理(打开/关闭会话)作为对存储库的响应而留下的,这是错误的。

+0

打开和关闭会话由单独的工作单元处理。然后将相同的工作单位传递给所有存储库,以使它们与同一工作单元相关联。我不把这个责任留给仓库本身。 – JMc 2011-04-01 11:52:31

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不在该方法的范围之内,认为它只需要声明一次。

+0

答案是2年前写的,所以到目前为止,你会擅长这个概念,但是ISession通常通过像Ninject或Castle Windsor这样的IoC容器注入到存储库类的构造函数中,以利用UoW的好处。 IRepository也被注入到您的业务类的构造函数中,所以您不必在开始时打开ISession并在结束时关闭它。 – Andy 2013-11-08 16:08:49

0

我也遇到了这个错误 - 但我只在一个中断点注意到它。我的错误是由于DebuggerDisplay属性试图显示正在被加载的属性。

相关问题