2012-02-15 63 views
1

我正在使用Ninject,流利的NHibernate和ASP.NET MVC。为什么NHibernate不跟踪对我的实体所做的更改?

到目前为止,一切工作正常,我没有得到任何错误,我能够从存储库中查询出很好,但我无法提交任何更改。

我控制器的方法是这样的

[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()为假。 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

你如何注入ISession到NHibernateSession.Current? – dotjoe 2012-02-15 21:54:05

+0

它没有真正注入。一个被调用的方法将构建一个SessionFactory并将其存储在我的NHibernateSession类的一个字段中。所以'.Current'会在需要时调用'SessionFactory.OpenSession'。 – Brandon 2012-02-15 21:57:29

回答

1

您需要为该请求使用相同的ISession,因此需要使用InRequestScope()。你可以改变NHibernateSession.Current为类似return DependencyResolver.Current.GetService<ISession>();但它可能是更优选构造函数注入的Isession到FilterAttribute告诉ninject它与this.BindFilter<UnitOfWorkFilter>(FilterScope.Action, 0);

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

+0

感谢您的回答,但我认为我的评论是误导性的。你能看到更新吗? 'GetExistingSession()'将在每次调用中返回相同的会话。 – Brandon 2012-02-15 22:15:02

+0

好吧,基本上是重新实现InRequestScope()。哪个ISession是动作方法使用?它是否也使用'Current'? – dotjoe 2012-02-15 22:19:49

+0

控制器没有引用,但Repository确实有一个注入其构造函数。我认为你是正确的,我的NhibernateSession类中的代码是从之前使用StructureMap的项目中获取的,在这个项目中这是必要的。它可能不适用于Ninject。 – Brandon 2012-02-15 22:20:32

1

从你的问题你的评论,我觉得每次你打电话NHibernateSession.Current你正在接受一个新的会议。那就是问题所在。您的会话需要具有每个Web请求的生命周期语义。您需要将会话注入控制器或过滤器。

+0

感谢您的回答,您能否看到更新?我应该更清楚我的意思是“是否需要”。 OpenSession不应该每次都被调用。当我调试时'GetExistingSession()'将返回相同的会话。 – Brandon 2012-02-15 22:13:56

相关问题