2012-02-15 64 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

相關問題