NHibernate-非法访问加载集合

NHibernate-非法访问加载集合,nhibernate,hbm,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

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

我的客户映射是:

<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>
然后,我尝试通过以下方式获得客户第一个帐户:

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();”成功


有人知道这里发生了什么吗?

我认为这很简单:您不再有与实体相关联的开放式会话。而且,我认为这是由于将会话管理(打开/关闭会话)作为存储库的责任,这是错误的。

这里的问题实际上是“ISession”已关闭,尽管这不是因为它按照前面的建议由单个存储库处理

问题的原因是我声明我的UnitOfWork(ISession)超出了我的业务方法-PlaceOrder()的范围。例如:

ISession myUnitOfWork = new ISession();


public void PlaceOrder()
{

    var myRepository = new IRepository<Customer>(myUnitOfWork);
    ....
    ....
    Commit();
}
ISession myUnitOfWork=新ISession();
公共秩序
{
var myRepository=新IRepository(myUnitOfWork);
....
....
提交();
}
因此,对PlaceOrder()方法的第一次调用没有问题,但在其他调用中,ISession已关闭,因此出现了“非法访问加载集合”消息。解决方案是在PlaceOrder()方法中声明ISession:

public void PlaceOrder()
{
ISession myUnitOfWork=新ISession();
var myRepository=新IRepository(myUnitOfWork);
....                

最终,这个问题是由于缺乏对工作单元概念的理解造成的是一个新事务,因此需要在开始时打开ISession,并在结束时关闭。我在方法范围之外声明ISession,认为它只需要声明一次。

我也收到此错误,但我只在断点处注意到它。我的错误是由调试程序显示attribute正在尝试显示延迟加载的属性。

打开和关闭会话由单独的工作单元类处理。然后将相同的工作单元传递给所有存储库,使它们与相同的工作单元相关联。我不会将此责任留给存储库本身。您是否尝试删除该任务“易变的"属性?答案是2年前写的,所以到目前为止,您将擅长这一概念,但ISession通常通过IoC容器(如Ninject或Castle Windsor)注入到存储库类的构造函数中,以利用UoW的优势。IRepository也被注入到业务类的构造函数中,因此您不必打开ISess在开始时打开,在结束时关闭。
var acc = from a in _accountRepository.GetAll()
                  where a.Customer.Equals(customer)
                  select a;
ISession myUnitOfWork = new ISession();


public void PlaceOrder()
{

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