2015-11-04 27 views
0

我正在嘗試創建一個UnitOfWork動作過濾器。DbContext ChangeTracker失去Web請求中的更改。通過行動過濾器

我鉤住OnActionExecuted方法,其中我想保存這取決於三個規則的所有更改的DbContext: -

  1. 上下文中NOT NULL。
  2. 上下文ChangeTracker HasChanges
  3. 否在ActionMethods存在的整個生命週期中都沒有發現異常。

在整個WEB API中的操作方法中,我只將實體附加到DbContext上,只有在操作本身完成而沒有任何錯誤時才執行更改。

DbContext在設置中使用Ninject和「InRequestScope」的生活方式。

這裏是的UnitOfWork ActionFilterAttribute: -

public class UnitOfWorkActionFilterAttribute : ActionFilterAttribute 
    { 
     public virtual IActionTransactionHelper ActionTransactionHelper 
     { 
      get { return WebContainerManager.Get<IActionTransactionHelper>(); } 
     } 

     public override bool AllowMultiple 
     { 
      get { return false; } 
     } 

     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      ActionTransactionHelper.BeginTransaction(); 
     } 

     public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
     { 

      ActionTransactionHelper.EndTransaction(actionExecutedContext); 
      ActionTransactionHelper.CloseSession(); 
     } 
    } 

在Ninject,所述的DbContext被配置是這樣的: -

container.Bind<MyDbContext>().ToSelf().InRequestScope(); 

這裏是ActionTransactionHelper級別: -

public class ActionTransactionHelper : IActionTransactionHelper 
    { 

     public bool TransactionHandled { get; private set; } 
     public bool SessionClosed { get; private set; } 
     public void BeginTransaction() 
     { 
      var sessionContext = WebContainerManager.Get<MyDbContext>(); 

      if (sessionContext == null) 
      { 
       throw new NullReferenceException("sessioncontext"); 
      } 

     } 

     public async Task EndTransaction(HttpActionExecutedContext filterContext) 
     { 
      var sessionContext = WebContainerManager.Get<MyDbContext>(); 

      if (sessionContext != null && sessionContext.ChangeTracker.HasChanges() && filterContext.Exception == null) 
      { 
       var x = await sessionContext.SaveChangesAsync(); 
      } 

      TransactionHandled = true; 
     } 

     public void CloseSession() 
     { 

      var sessionContext = WebContainerManager.Get<MyDbContext>(); 

      if (sessionContext == null) return; 
      sessionContext.Dispose(); 

      SessionClosed = true; 
     } 
    } 

我有一個Action方法,它將這樣的實體附加到DBContext上: -

context.Claims.Add(entity); 

當endTransaction()方法的方法是在燒製ActionExecuted,上下文對象具有在任何變化ChangeTracker和SaveChangesAsync()方法從來沒有發射任何記錄。

但是,如果我將DbContext的Ninject Binding更改爲Singleton,則代碼可以正常工作,更改將被跟蹤並且對象將保存到數據庫中。

我不明白爲什麼這不是每個Web請求都有效?

我不想在這種情況下使用單身人士。

回答

1

此問題已通過添加Ninject.WeApi2 Nuget包得到解決。

在NinjectWebCommon我更換了NinjectDependencyResolver實現與一個在Ninject.WeApi2

**Ninject.Web.WebApi.NinjectDependencyResolver** 

InRequestScope引用()現在正常工作與措施篩選器和跟蹤的DbContext變化。