为什么ASP.NET MVC WebAPI模板使用DbContext作为成员变量?

时间:2015-02-19 23:30:18

标签: asp.net-mvc entity-framework asp.net-web-api

如果您在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模板使用成员变量方法?

1 个答案:

答案 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使用每个网络请求的生活方式。

在这里展示一个完整的例子可能有点冗长,超出了问题的范围。