2009-10-17 88 views

回答

3

我不会推荐它,除非你真的知道你在做什么。关闭我的头顶:

  • 存储在httpsession中的实体必须是完全可序列化的,否则非进程内会话存储将会中断。
  • 除非您明确将实体重新附加到新会话,否则延迟加载将会中断。

如果您想要交叉请求对话检查NHibernate.Burrow这是一个专为此特定目的而设计的框架。

0

使用NHibernate的“每个请求的会话”与HttpSession没有关系。会话中每个请求的“会话”是NHibernate ISession。在请求开始时将NHibernate.ISession存储在HttpContext.Current.Items中是安全的,并在请求结束时处理它。

+1

我知道。也许我没有说清楚,然而问题是NH ISession是否在请求结束时处理完毕,是否可以安全地将实体(从NH ISession加载)存储在(Http)会话中。我很确定这是有问题的,但我想知道引入了哪些问题。 – jeroenh 2009-10-18 12:37:05

+0

在HttpSession中存储大对象最大的问题是内存泄漏。您可以更好地存储对HttpSession中的大对象的引用,而不是大对象本身 – Paco 2009-10-18 13:22:18

0

是的,你可以,如果你正在基于一个不是主键的属性来获取它,那么缓存一个经常使用的对象是有意义的。

我的网站有一个Person类,它代表网站上的特定用户。在任何给定的Web请求中,我需要多次获取当前登录的用户对象以访问特定于当前用户的各种配置设置和属性。我不是每次都敲击数据库,而是将当前用户存储在HttpContext.Items []中,并且我有一个静态方法来检查项目缓存是否包含当前用户。如果是这样,则返回它,如果它不从数据库中获取它并将其添加到缓存,以便其可用的下一次:

public static Person CurrentUser 
    { 
     get 
     { 
      if(!IsAuthenticated) return null; 
      Person person = (Person) HttpContext.Current.Items[HttpContext.Current.User.Identity.Name]; 
      if(person != null) return person; 

      IPersonDao personDao = new PersonDao(); 
      person = personDao.getByUsernameEmail(HttpContext.Current.User.Identity.Name); 
      if(person==null) 
      { 
       FormsAuthentication.SignOut(); 
       HttpContext.Current.Response.Redirect("/"); 
      } 
      HttpContext.Current.Items[HttpContext.Current.User.Identity.Name] = person; 
      return person; 
     } 
    } 

我也有我的NHibernate会话对象存储在HttpContext.Items这样对话并且缓存的对象将在HttpRequest的最后同时被垃圾回收,你不想要的是让对象在会话的整个生命周期中存活,否则可能会启动一个新的会话,并且NHibernate将会使用NHibernate.NonUniqueObjectException,因为该对象绑定到另一个会话。

它的值得指出的是,NHibernate的1st级缓存保留了由ID缓存的会话访问的所有对象。如果我正在调用session.get(id),则不需要缓存,因为NHibernate的第一级缓存通过它们的id维护对象。但是在上述通过User.Identity.Name获取person对象的情况下,第一级缓存不起作用,因为用户的用户名不是对象的主键。在HttpContext.Items

更多信息http://aspnet.4guysfromrolla.com/articles/060904-1.aspx

不要使用HttpContext.Cache,由于某种原因持续的时间超过HTTP请求。

+1

问题是关于HttpContext会话,而不是**关于HttpContext.Items – 2009-10-30 02:54:19

相关问题