如何跨Action过滤器和控制器传递工作单元/实体上下文

时间:2014-06-19 16:55:29

标签: asp.net-mvc entity-framework controller action-filter

我正在尝试确保我的MVC应用程序仅为每个请求使用一个DbContext,以减少Db连接打开的次数,因此没有并发问题。

这意味着我需要在全局动作过滤器和控制器中使用相同的上下文。

我尝试过这样的事情

public class LayoutFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        MembershipUser loggedInUser = Membership.GetUser();

        MyUnitOfWork uow = new MyUnitOfWork();
        ViewBag.FullName = uow.UserService.GetUser().FullName

        filterContext.ActionParameters["unitOfWork"] = uow;
    }
}

然而,当我尝试从控制器读取它时,上下文被处理,如下所示

  public ActionResult Logout(MyUnitOfWork uow)
    {
        ViewBag.Something = uow.ExampleService.GetMyObject();

        return RedirectToAction("LogIn");
    }

当我尝试通过强制转换基本控制器类的属性来共享同一个unitOfWork对象时,我遇到了相同的上下文问题

public class BaseController : Controller
{
    public RequestboxUnitOfWork unitOfWork;
}

 public class LayoutFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        MembershipUser loggedInUser = Membership.GetUser();

        BaseController baseController = (BaseController)filterContext.Controller;
        ViewBag.FullName = baseController.unitOfWork.UserService.GetUser().FullName

        filterContext.ActionParameters["unitOfWork"] = uow;
    }
}

当我尝试在控制器中访问它并且我在几个地方读过你不应该使用基本控制器类时,上下文被处理掉了所以我不确定我能做什么。

在ActionFilters和Controllers之间共享实体上下文的推荐方法是什么

1 个答案:

答案 0 :(得分:1)

创建DBContext作为Controller设置的一部分,并通过控制器上的内部属性使其可用。

public class MyController : Controller
{
    private MyUnitOfWork unitOfWork;

    internal MyUnitOfWork UnitOfWork 
    { 
        get { return unitOfWork; } 
    }
}

然后,您将能够访问过滤器属性中的上下文,如下所示:

MyController controller = (MyController)filterContext.Controller
MyUnitOfWork uow = controller.UnitOfWork;

没有必要将工作单元传递回控制器中的action方法,因为控制器已经有了对象,并且可以通过相同的内部属性访问它。