在ASP.NET MVC中实例化EF4上下文?

时间:2011-07-15 06:49:20

标签: c# asp.net-mvc entity-framework instantiation

我找到了a tutorial in microsoft asp.net website,它从上下文中创建了一个实例:

        public class HomeController : Controller
        {
            private MoviesDBEntities _db = new MoviesDBEntities(); 

            public ActionResult Index()
            {
                return View(_db.MovieSet.ToList());
            }

            ...
        }

这意味着每次控制器实例化时,上下文也将实例化。但Here我发现实例化上下文的正确方法是这样的:

        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                using(MoviesDBEntities _db = new MoviesDBEntities()){
                    return View(_db.MovieSet.ToList());
                }
            }
            ...
        }

所以问题是,哪种方式是正确的?或者它是否重要?

3 个答案:

答案 0 :(得分:6)

通常,类不应该负责实例化自己的依赖项。

最好的办法是将依赖项传递给构造函数: -

public class HomeController : Controller
{
  private IMovieRepository _db;
  public HomeController(IMovieRepository db)
  {
    _db = db;
  }

  public ActionResult Index()
  {
    return View(_db.MovieSet.ToList());
  }
}

这称为“依赖注入”,它是可取的,因为它减少了样板代码,并且还允许您在运行时提供其他IMovieRepository实现(例如,如果您是单元测试)。

ASP.NET MVC有一个允许你这样做的钩子(ControllerBuilder),但幸运的是你不需要自己动手,有预先制作的解决方案。我建议使用http://ninject.org/,因为它很容易设置。

这样你的IoC容器(无论是什么传递依赖)都可以为每个HTTP请求仅实例化一个上下文,并在请求结束时处理它。

查看例如What is Inversion of Control?

答案 1 :(得分:2)

所有这些都是为了释放资源。

在有状态的情况下,对象更有可能活得更久,因此使用语句最好在使用后立即处理它。

在无状态情况下(即asp.net),服务器接收请求,生成结果,将其发回并处理使用过的资源(包括上下文)。

如果您知道几乎所有方法都可能在无状态情况下使用特定上下文,那么将它作为一个字段并在对象创建时实例化上下文而不是在每个方法中输入它会更容易一些。

答案 2 :(得分:1)

第二个更好,因为当自动超出范围时,using语句将自动释放IDisposable ObjectContext消耗的资源。

在我看来,官方asp.net网站上的例子通常只是“工作”,而不是如何构建应用程序的好例子。