我有一个VS 2010项目,我从中生成了一个exe并设置了一个计划任务。但是每当任务运行时,我在NHibernate.cs文件中收到错误,说当前会话为空
public static ISession GetCurrentSession()
{
return SessionFactory.GetCurrentSession();
}
我如何克服这个问题?这是否需要以编程方式验证会话是否存在?
答案 0 :(得分:1)
提供的信息(包括代码段)的集合根本不足以说明 - 究竟是什么错误。无论这个事实如何,都有一个非常普遍的怀疑:
System.Web
基础架构运行时) 检查当前会话持久性(Http.Context,Thread ...)的设置和实现。为了获得更多的理解,请从文档开始:
摘录:
大多数使用NHibernate的应用程序需要某种形式的“上下文”会话,其中给定的会话在给定上下文的范围内有效。但是,在不同的应用程序中,构成上下文的定义通常是不同的;不同的上下文定义了当前概念的不同范围。
从版本1.2开始,NHibernate添加了
ISessionFactory.GetCurrentSession()
方法。ISessionFactory.GetCurrentSession()
背后的处理是可插拔的。添加了扩展接口(NHibernate.Context.ICurrentSessionContext
)和新配置参数(hibernate.current_session_context_class
),以允许定义当前会话的范围和上下文的可插入性。
文档中的示例显示了在Web环境中会话持久性的自定义实现 - Chapter 1. Quickstart with IIS and Microsoft SQL Server
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}
即。在控制台应用程序(代表单个操作)中,我们可以将会话放在某个程序实例属性中......并在执行期间使用它。
答案 1 :(得分:1)
我需要以编程方式验证会话是否存在吗?
是的,如果要使用当前会话机制来控制跨多个应用程序块的会话的生命周期,则需要打开会话并将会话绑定到CurrentSessionContext
。
此外,您需要指定要使用的CurrentSessionContext
类型,NHibernate提供了不同的默认实现,例如: Web场景或控制台之类的应用程序原因是会话将绑定到不同类型的状态实例。
在Web方案中,实现使用System.Web.HttpContext.Current.Items
。这可以确保会话在一个http请求中存活。
在控制台应用程序中以及在您的方案中,您将使用ThreadStatic
会话上下文。这个确保每个线程你有一个会话。
要将会话绑定到CurrentSessionContext
,您必须打开并绑定它(会话工厂必须首先构建/一次构建。
var session = sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
从现在开始sessionFactory.GetCurrentSession();
将返回该会话。
您应该在范围结束时关闭并处置会话,例如你的线程终止或请求结束(在网络应用程序中)。
您可以配置nhibernate以使用特定上下文。使用Fluently配置它看起来像这样:
Fluently.Configure()
....
.CurrentSessionContext("thread_static")