如果您在Visual Studio 2013中创建一个WebAPI / MVC项目,请添加Model(和DbContext类)以及此模型的Controller,如下所示 -
http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-2,
它创建了一个控制器,将DbContext声明为一个成员变量,这是根据许多stackoverflow的答案/在线arcticles,是一个坏主意 - 就像这个
https://stackoverflow.com/a/10588594
Visual Studio生成的控制器方法 -
// GET: api/Authors
public IQueryable<Author> GetAuthors()
{
return db.Authors;
}
如果您使用建议的每个请求生命周期,则无效 -
// GET: api/Authors
public IQueryable<Author> GetAuthors()
{
DbSet<Author> authors = null;
using(MyContext db = new MyContext) {
authors = db.Authors;
}
return authors;
}
因为在结果迭代结束时上下文超出了范围,并且您获得了一个对象处理异常。
那么,正确的方法是什么,如果它是每个请求方法的“使用”,为什么VS模板使用成员变量方法?
答案 0 :(得分:4)
原因是因为这是一个简单的起点。
使用ASP.NET MVC很容易理解,也很容易上手。
将DbContext
作为在控制器级别创建的成员变量没有任何问题,尽管它可能并不理想。随着应用程序变得越来越复杂,它就不太适合。
[...]根据许多stackoverflow答案/在线arcticles,是一个坏主意
我没有从你联系到的答案中得到那个。
Steven解释说单个DbContext (即全局)或每个线程的上下文是错误的。
如果您使用建议的每个请求生存期
,则无效
这不是每个请求的生命周期。这几乎就像一个工作单元模式,但你没有做任何事情。
你想要做的事情的解决方案是
// GET: api/Authors
public IEnumerable<Author> GetAuthors()
{
IEnumerable<Author> authors = null;
using(MyContext db = new MyContext())
{
authors = db.Authors.ToList();
}
return authors;
}
在我看来,处理这个问题的正确方法是使用IoC Container对DbContext使用每个网络请求的生活方式。
在这里展示一个完整的例子可能有点冗长,超出了问题的范围。