在控制器中的函数之外声明DBContext的错误做法是什么?

时间:2015-07-29 15:38:36

标签: c# asp.net .net asp.net-mvc

假设我有一个如下控制器:

public class MyController : Controller
{
    private MyDBContext db = new MyDBContext();

    public ActionResult Index()
    {
        return View(db.Items.ToList());
    }
...

通常当我需要进行EF调用时,我将在我使用它的函数中实例化DBContext并将其包装在using语句中,如下所示:

    public ActionResult Index()
    {
        using(MyDBContext db = new MyDBContext())
        {
            return View(db.Items.ToList());
        }
    }

我发现first example on the www.asp.net website似乎是一个声誉良好的来源(对吧?),但我担心每次使用后都不会手动处理上下文。

在没有using语句的情况下,在函数范围之外定义的上下文是不好的做法吗?

2 个答案:

答案 0 :(得分:0)

如果你有这样的东西,那就没有了:

hash = {
  bla_bla: {
    # these attributes should be whatever is defined in the Serializer 
  }
}

由于protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } 是一次性的,所以没问题 但通常我会尝试在我的控制器和模型之间进行更好的分离。

答案 1 :(得分:0)

第一种方式是"推荐"方式,因为在处理控制器时将处理上下文。由于控制器在请求的生命周期中存活,因此您确保您的上下文也会在整个时间内保持不变。将using与上下文一起使用是危险的,因为上下文被置于请求中的不同点,并且如果在它被处置之后被访问则可能导致问题。你可能在这里好,因为返回在using块内,但假设你做了类似下面的事情,而是:

List<Item> items;
using(MyDBContext db = new MyDBContext())
{
    items = db.Items.ToList();
}

return View(items);

第一次访问碰巧延迟加载的导航属性时,您将处于一个受伤的世界。虽然你没有在你的代码中犯这个错误,但总的来说很容易做到。如果你完全避免using与你的情境相关,那么你总是很好。

也就是说,最佳方式实际上是使用依赖注入。出于所有意图和目的,您的上下文应该被视为一个单例 - 您不希望多个实例浮动,因为这是一个灾难的处方。使用DI容器是一种很好的方法,可以确保无论在何处以及使用上下文的方式多少都可以实现。使用哪种DI容器是一种非常个性化的选择。我更喜欢Ninject,但还有其他一些选择可能更适合你的个人风格。无论你使用哪种方式,都应该有一些使用&#34;请求范围&#34;的选项。这就是您要在上下文中使用的内容,因为它确保每个请求只有一个实例,但每个请求都有自己的实例。