2011-11-30 58 views
0

我正在使用NH将数据库映射到名为location的对象,该对象具有一些属性,并且列表<Attachments>附件(与lcocation的实例具有一对多关系)。无法在n层web应用程序中执行延迟加载

我用lambda表达式来初始化location istance:

public IList<T> GetAllByExpression(Expression<Func<T,bool>> expression) 
     { 
      using (ISession session = NHibernateHelper.OpenSession()) 
      { 
       return session.Query<T>().Where(expression).ToList(); 
      } 
     } 

在我尝试访问location.attachments集合,但得到一个异常代码中的一些后来点:

{"Initializing[Location#543c7367-08fa-4469-a252-8e2c6163be22]-failed 

懒洋洋地初始化一个角色集合:Location.Attachments,没有 会话或会话已关闭“}

我明白这个会议已经结束,但我没有什么可以做的。

我明白会议已经结束,但我无能为力。

我有一个困境: 1)代码使用从数据库中提取后的集合,并需要会话仍然是开放的。 将会话全部开放是一种不好的做法。 (没有using)。

2)即使我在整个应用程序运行时期间打开会话,我也构建了一个n层Web应用程序。 DAL应该是通用的,并且不公开某些实现的会话(本例中为NH)。

3)急切的加载似乎是解决方案,但它是浪费 - 因为我必须急切地加载所有数据,以防其中包含其他对象列表的对象。 (甚至可以继续循环)

我该怎么办?

TIA

回答

1

正如Jason所说,这是因为你关闭了会议。

如果您正在使用Web窗体,那么您可能需要查看Session Per Request,其中会话在Http Request开始时打开,并在Http Request结束时关闭。 (针对这些RequestBegin/RequestEnd事件的全局asax)

这将使您能够延迟加载。

或者,您可以通过实现一个您传递到存储库的提取策略,以“在获取我的根的同时获取相关数据”来热切获取您想要的数据。

3

心理调试上:

看起来你要加载在收集你已经关闭了在会议结束后,或者您正试图加载上一个比一个不同的会话集合加载根实体。

不要这样做。

+0

但我不能让会议永远开放? –

+0

@Elad Benda:你不应该。对于单个工作单元,会话应该是短暂的。 – jason

+0

所以我从ORM初始化了一个Location对象,后来我不得不解决它中的“附件”集合(一对多关系)。我怎样才能做到这一点? –