C# 如果会话被释放,我必须使用即时加载吗?

C# 如果会话被释放,我必须使用即时加载吗?,c#,nhibernate,domain-driven-design,C#,Nhibernate,Domain Driven Design,请参阅下面的代码: public Enquiry GetByID(Guid personID) { using (IUnitOfWork<ISession> unitOfWork = UnitOfWorkFactory.Create()) { IRepository repository = RepostioryFactory.Create(unitOfWork); var Person = repository.GetById(per

请参阅下面的代码:

public Enquiry GetByID(Guid personID)
{
    using (IUnitOfWork<ISession> unitOfWork = UnitOfWorkFactory.Create())
    {
        IRepository repository = RepostioryFactory.Create(unitOfWork);
        var Person = repository.GetById(personID);
        return Person;
    }
}
公众查询GetByID(Guid personID)
{
使用(IUnitOfWork unitOfWork=UnitOfWorkFactory.Create())
{
IRepository repository=repositoryFactory.Create(unitOfWork);
var Person=repository.GetById(personID);
返回人;
}
}
它包含在应用程序服务层中。Person被传递回控制器并加载到视图中。视图随后出错,因为它无法加载Person.Collection(列表)


我相信这是因为集合是使用延迟加载加载的,一旦到达视图,工作单元和NHibernate会话就会关闭。在这种情况下,我必须使用急切加载,还是我误解了什么

我意识到会话将在方法完成之前结束(使用块将其包装在
中),这是在视图代码运行之前。因此,您确实需要在从NHibernate会话返回的
查询
类型中加载collection属性中的项目

一种更好的方法是设置工作单元模式,使其环绕管道中的整个请求。例如,如果您有一个
Global.asax
文件,它有两个方法,分别称为
Application\u BeginRequest
Application\u EndRequest

应用程序\u BeginRequest
方法将创建一个新的NHibernate会话,您的控制器可以检索该会话

Application\u EndRequest
方法只需刷新会话,即可将任何数据更改保存到基础数据库中


关于将NHibernate会话与
Global.asax
组件合并,我建议您参考以下StackOverflow问题:

我意识到会话将在方法完成之前结束(使用
块将其包装在
中),这是在您的视图代码运行之前。因此,您确实需要在从NHibernate会话返回的
查询
类型中加载collection属性中的项目

一种更好的方法是设置工作单元模式,使其环绕管道中的整个请求。例如,如果您有一个
Global.asax
文件,它有两个方法,分别称为
Application\u BeginRequest
Application\u EndRequest

应用程序\u BeginRequest
方法将创建一个新的NHibernate会话,您的控制器可以检索该会话

Application\u EndRequest
方法只需刷新会话,即可将任何数据更改保存到基础数据库中


关于将NHibernate会话与
Global.asax
组件合并,请参考以下StackOverflow问题:

IMHO延迟加载是邪恶的

存储库背后的想法是返回聚合。该汇总表应包含构成汇总表的所有相关数据。它从不以位加载。因此,应该总是急切地获取聚合

如果从等式中删除UoW/ORM,那么延迟加载就不是一个选项

您应该尽量不要查询您的域。如果您的情况是,单个聚合包含您需要的所有数据,并且该数据已经公开,那么就可以了


但是,我建议您使用read模型。一个简单的查询层。尝试一下,你可能会感到惊讶:)

我认为懒惰加载是邪恶的

存储库背后的想法是返回聚合。该汇总表应包含构成汇总表的所有相关数据。它从不以位加载。因此,应该总是急切地获取聚合

如果从等式中删除UoW/ORM,那么延迟加载就不是一个选项

您应该尽量不要查询您的域。如果您的情况是,单个聚合包含您需要的所有数据,并且该数据已经公开,那么就可以了


但是,我建议您使用read模型。一个简单的查询层。尝试一下,您可能会感到惊讶:)

引入视图模型层而不是将原始实体传递给控制器将解决您的问题,因为映射到
Person
视图模型(在
using
子句中)将访问
Person.Collection
并触发加载


或者,正如@EbenRoux所建议的,您可以有一个不经过域的整个读取端。

引入视图模型层而不是将原始实体传递给控制器将解决您的问题,因为映射到
视图模型(在
中使用
子句)将访问
Person.Collection
并触发加载

或者,正如@EbenRoux所建议的,您可以拥有一个不经过域的整个读取端

在这种情况下,我必须使用急切加载,还是我误解了什么

嗯,你想,是吗?您正处于一个用例中,您知道您希望Person.Collection可用,所以为什么不立即加载它呢

诀窍是不要使用与希望延迟加载集合(或根本不加载)时使用的相同的存储库实现

乌迪·达汉对此写了很多次

Greg Young会提醒您,抓取策略的使用是一个实现细节,而不是合同的一部分

在这种情况下,我必须使用急切加载,还是我误解了什么

嗯,你想,是吗?您正处于一个用例中,您知道您希望Person.Collection可用,所以为什么不立即加载它呢

诀窍是不要使用与希望延迟加载集合(或根本不加载)时使用的相同的存储库实现

乌迪·达汉对此写了很多次