假设我有一个如下控制器:
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
语句的情况下,在函数范围之外定义的上下文是不好的做法吗?
答案 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;的选项。这就是您要在上下文中使用的内容,因为它确保每个请求只有一个实例,但每个请求都有自己的实例。