我正在使用NHibernate 3开始一个新项目,我正在尝试使用带有WebSessionContext的CurrentSessionContext API来管理我的ISession对象。
在以前的项目中,我总是自己管理,所以每当我需要一个ISession对象时,我会创建它并存储在HttpContext.Items集合中。非常简单,但使用本机解决方案(CurrentSessionContext)似乎是这个新项目的最佳选择。
当我管理对象时,我能够对它进行延迟初始化,这意味着我只在需要时打开一个Session而不是在每个请求中打开,因为我可能不需要它,并且会浪费资源/时间一直打开它。
使用CurrentSessionContext API有一种简单的方法吗?
以下是我在负责此操作的HttpModule中使用的代码:
public class ContextualSessionModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
context.EndRequest += context_EndRequest;
}
public void Dispose()
{
}
private static void context_BeginRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
var context = application.Context;
BindSession(context);
}
private static void BindSession(HttpContext context)
{
// Create a new session (it's the beginning of the request)
var session = SessionBuilderFactory.CurrentSessionFactory.OpenSession();
// Tell NH session context to use it
CurrentSessionContext.Bind(session);
}
private static void context_EndRequest(object sender, EventArgs e)
{
var application = (HttpApplication)sender;
var context = application.Context;
UnbindSession(context);
}
private static void UnbindSession(HttpContext context)
{
// Get the default NH session factory
var factory = SessionBuilderFactory.CurrentSessionFactory;
// Give it to NH so it can pull the right session
var session = CurrentSessionContext.Unbind(factory);
if (session == null) return;
session.Flush();
session.Close();
}
}
修改
迭戈几乎把它钉了下来,但我想到了更多关于这一点,我想起了我自己实现控制的主要原因:交易。我是Onion Architecture家伙,所以我的域对象(知道何时开始交易的人)无权访问基础架构,因此无法启动交易。
为了解决这个问题,我使用延迟初始化并在打开Session时始终启动事务。提交在请求结束且没有捕获异常时发生。 除此之外,Ayende建议总是使用交易,即使在查询时也是如此。有什么想法吗?
答案 0 :(得分:3)
虽然不是直接回答你的问题,但我认为:为什么?
会话是一个轻量级对象。如果你不使用它,它只是初始化一些内部结构,但它不会打开数据库连接或任何东西。
为了节省一点时间/内存,有一些例子(仅谷歌)可以避免打开静态对象的会话。除此之外,它可能不值得,除非你的分析表明它会伤害你的表现。
更新:有关交易需求,请查看uNhAddIns中的CpBT实现。