我正在使用Ninject,Fluent NHibernate和ASP.NET MVC。
到目前为止,一切工作正常,我没有收到任何错误,我可以很好地查询存储库,但我无法进行任何更改。
我的控制器方法如下所示
[HttpPost]
[UnitOfWork]
public ActionResult Method(int id)
{
// Lookup entity, toggle a bool property on it and that is it
}
我的UnitOfWork属性如下所示
public class UnitOfWorkAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
NHibernateSession.Current.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception == null && NHibernateSession.Current.Transaction.IsActive)
{
NHibernateSession.Current.Transaction.Commit();
}
}
}
正在调用这两个方法并且不会引发任何错误,问题是当调用NHibernateSession.Current
(只返回NHibernate.ISession
)时,ISession.IsDirty()
为false。 NHibernate认为没有任何改变。
我之前在其他项目中使用了类似的设置,没有问题,唯一不同的是我换了Ninject的StructureMap,我不熟悉。
相关的绑定是
Bind<IEntityRepository>().To<EntityRepository>().InRequestScope();
Bind<ISessionFactory>().ToMethod(x => NHibernateSession.CreateSessionFactory()).InSingletonScope();
Bind<ISession>().ToMethod(x => x.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
任何想法我做错了什么?我猜这与我弄乱会话处理有关,但我不确定究竟是什么。
编辑:这是当前调用返回的内容。应存储会话,以便不必每次都创建新会话。
public static ISession Current
{
get
{
var session = GetExistingSession();
if (session != null)
return session;
session = _sessionFactory.OpenSession();
HttpContext.Current.Items[SessionKey] = session;
return session;
}
}
答案 0 :(得分:1)
您需要为该请求使用相同的ISession,因此InRequestScope()
。您可以将NHibernateSession.Current更改为return DependencyResolver.Current.GetService<ISession>();
之类的内容,但可能更倾向于将ISession注入FilterAttribute并通过this.BindFilter<UnitOfWorkFilter>(FilterScope.Action, 0);
https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations
答案 1 :(得分:1)
根据您对问题的评论,我认为每次拨打NHibernateSession.Current
时,您都会收到一个新会话。那就是问题所在。您的会话需要具有每个Web请求的生命周期语义。您需要将会话注入控制器或过滤器。