在httpcontext.current.session中缓存nhibernate实体是否有意义?

时间:2009-10-17 22:48:18

标签: asp.net nhibernate session

我正在学习NHibernate并且正在研究最近在ASP.Net MVC项目中使用NHibernate的一些代码。

在此应用程序的某个部分中,从NH加载的实体将保留在(HttpContext)会话中。如果你使用(NHibernate)Session-per-request模式,这样可以,或者是否有任何危险?

3 个答案:

答案 0 :(得分:3)

除非你真的知道自己在做什么,否则我不会推荐它。在我的头顶:

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

如果您想进行交叉请求对话,请查看NHibernate.Burrow,这是专为此特定目的而设计的框架。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

是的,如果您根据不是主键的属性获取常用对象,则可以缓存常用对象。

我的网站有一个Person类,代表网站上的特定用户。在任何给定的Web请求中,我需要多次获取当前登录的用户对象,以访问特定于当前用户的各种配置设置和属性。我没有每次都访问数据库,而是将当前用户存储在HttpContext.Items []中,并且我有一个静态方法来检查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进行barf,因为该对象绑定到另一个会话。

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

有关HttpContext.Items http://aspnet.4guysfromrolla.com/articles/060904-1.aspx

的更多信息

请勿使用HttpContext.Cache,因为某些原因会超出Http请求。