在我的Web应用程序中,在请求周期的某个地方,我在存储库上调用以下方法:
repository.Delete(objectToDelete);
这是NHibernate实现:
public void Delete(T entity)
{
if (!session.Transaction.IsActive)
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Delete(entity);
transaction.Commit();
}
}
else
{
session.Delete(entity);
}
}
session.Delete(entity)(在using语句中)失败 - 这很好我有一些数据库约束,这就是我的预期。但是,在 Global.asax.cs 中的请求结束时,我使用以下代码关闭会话:
protected void Application_EndRequest(object sender, EventArgs e)
{
ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, sessionFactory);
if (session != null)
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
}
else
{
session.Flush();
}
session.Close();
}
}
这是用于删除对象的同一会话。现在,时间:
session.Flush();
调用,NHibernate尝试执行相同的DELETE操作 - 抛出异常和应用程序崩溃。不完全是我想要的,因为我之前已经处理过异常(在存储库级别)并且我显示了preety UI消息框。
当调用session.Flush时,如何防止NHibernate再次尝试执行DELETE(我猜其他方案中的UPDATE操作)操作。 Basicall我没有设计 Application_EndRequest 所以我不确定这是否是一个很好的方法来刷新一切。
由于
答案 0 :(得分:1)
NHibernate的刷新模式默认设置为“auto”,这意味着(除其他事项外)提交事务将导致NHibernate刷新并且删除失败。
在请求结束时,您再次手动刷新会话,告诉NHibernate再次执行删除(因为没有活动事务)。
这不符合预期的原因是因为您的期望是错误的。 NHibernate会话是一个工作单元,即您的应用程序在一个请求中执行的所有操作。 交易完全不相关。第一次刷新会话失败的事实也是第二次失败的原因。
如果你想阻止NHibernate第二次执行删除,你不应该只刷一次,只刷一次。通过提交事务或手动完成。
在某种程度上不相关的说明:你使用NHibernate并且交易错误。它会在以后给你带来大量的问题。关于如何在Web应用程序中使用NHibernate,有一些很好的在线资源。