2009-10-17 89 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

相關問題