为什么不是';t NHibernate跟踪对我的实体所做的更改

本文关键字:实体 我的 跟踪 NHibernate 为什么不 | 更新日期: 2023-09-27 18:24:40

我使用的是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认为没有任何变化。

我以前在其他项目中使用过类似的设置,但没有遇到任何问题,唯一的区别是我把StructureMap换成了我不太熟悉的Ninject。

相关绑定是

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;
   }
 }

为什么不是';t NHibernate跟踪对我的实体所做的更改

您需要为该请求使用相同的ISession,因此InRequestScope()。您可以将NHibernateSession.Current更改为类似return DependencyResolver.Current.GetService<ISession>();的内容,但可能更倾向于将ISession ctor注入FilterAttribute,并用this.BindFilter<UnitOfWorkFilter>(FilterScope.Action, 0); 告诉ninject

https://github.com/ninject/ninject.web.mvc/wiki/Filter-configurations

根据您对问题的评论,我认为每次您致电NHibernateSession.Current时都会收到一个新的会话。这就是问题所在。您的会话需要具有每个web请求的生存期语义。您需要将会话注入控制器或筛选器。