我应该在MVC应用程序中的哪个位置创建实体框架上下文对象?

时间:2010-10-28 14:08:56

标签: asp.net-mvc entity-framework

我想使用Session-per-request模式,就像在ASP.NET环境中使用NHibernate时经常做的那样。

我的第一个想法是将代码放在Global.asax中的BeginRequest事件处理程序中创建上下文,但我发现这个事件不仅针对实际完成工作的初始请求,而且针对后续事件请求静态文件,如CSS和图像。

我不想在不需要的时候创建一大堆额外的上下文,所以有没有办法让我的代码在初始请求上运行,而不是静态文件的代码?

4 个答案:

答案 0 :(得分:4)

  1. 对需要上下文的任何内容使用构造函数注入。
  2. 使用您选择的DI框架并映射上下文。
  3. 将上下文作为请求范围限定。

答案 1 :(得分:2)

如果您使用集成管道(默认设置)在IIS 7中运行,则ASP.NET模块将看到每个请求,甚至是静态内容请求(请参阅http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/),

如果您仍然希望使用HTTP模块来管理每个请求的会话/内容,我会考虑使用Lazy来避免在不需要时实例化上下文。

如果使用动作过滤器,如果在OnActionExecuted期间处置上下文,则需要提前完成所有工作。如果要延迟查询执行直到视图呈现,或者使用延迟/延迟加载实体,请在OnResultExecuted期间等待并释放。

正如Craig所指出的,IoC容器还可以为您管理生命周期。

答案 2 :(得分:1)

当我使用依赖注入框架时,我通常有一个单独的程序集,其中包含域模型。该程序集还包含存储库的接口。存储库的实现包含实际实例化EF ObjectContext的代码。

如果这是一个非常简单的应用程序而你没有做DI,你总是可以在控制器的构造函数中实例化EF ObjectContext。查看http://www.asp.net/mvc上的ASP.NET MVC示例应用程序,了解有关入门的基本信息。我认为他们现在使用EF的所有三个示例应用程序。

答案 3 :(得分:1)

您是否使用带有通配符映射的IIS 6? CSS和图像不应该触发BeginRequest。

另一种流行的方法是覆盖基本Controller内部的OnActionExecuted和OnActionExecuting方法。

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _context = new SomeEntities();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        _context.Dispose();
        base.OnActionExecuted(filterContext);
    }