为什么没有人在WebApi控制器操作后处理DbContext?

时间:2013-12-30 09:34:53

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

我了解各种教程以及定位WebApi&的完整示例。具有Entity Framework控制器的WebApi(甚至来自Microsoft):

public HttpResponseMessage GetInternet(int id) {
    var context = new InternetDbContext();
    var result =
       (from internet in context.Internets
        where internet.Id.Equals(id)
        select internet).FirstOrDefault();
    if(result != null)
       Request.CreateResponse(HttpStatusCode.OK, result);
}

但是当我在2年前了解Entity Framework时,我发现的关于该框架的每一个资源都指出了 DISPOSE <{1}}中的<{1}}非常重要。 strong> SHORTEST 可能的寿命,例如使用'DbContex'。而现在,人们似乎并没有放弃处理任何东西(他们的经理,存储库,DI容器......)。

我在这里遗漏了什么吗? API调用的结尾是否会自动处理上下文?或者我是否必须使用http://msdn.microsoft.com/en-us/library/dn153859(v=vs.118).aspx中的using

6 个答案:

答案 0 :(得分:9)

就个人而言,每当我看到类型实现IDisposable时,我几乎肯定在处理这种类型的新实例时我将使用using语句。

当变量超出范围时(例如,当执行从context方法返回时,GetInternet变量超出范围),其内存最终将被垃圾回收收集器但这并不意味着任何本机处理程序(例如文件处理程序或数据库连接)将被关闭,这会对您的应用程序产生非常严重的负面影响。

因此,请考虑始终IDisposable包装到using构造中:

using (var context = new InternetDbContext())
{
  // Your code goes here
}

希望这有帮助。

答案 1 :(得分:2)

有时处理上下文是一个坏主意。例如,我有一个像这样的WebAPI2控制器方法,

    [Route("Questionnaires")]
    public IEnumerable<Questionnaire> GetAllQuestionnaires()
    {
        NMQContext context = new NMQContext();
        return context.Questionnaires.AsEnumerable();
    }

结果数据是JSON列表,调查表是一个复合对象 - 它包含来自多个数据库表的实体。如果我用“使用”包装它,我会收到错误,例如

   "Message": "An error has occurred.",
   "ExceptionMessage": "The operation cannot be completed because the DbContext has been disposed.",

如果您尝试序列化复合对象,那么最好不要处置连接。最好让EF为你处理它。您可以通过明确的急切加载来修复它,但这很痛苦。不要这样做。

答案 2 :(得分:1)

using的Prime案例,无论退出方法如何,您的DbContext都将被处置;

public HttpResponseMessage GetInternet(int id) {
    using(var context = new InternetDbContext()) {
        var result =
           (from internet in context.Internets
            where internet.Id.Equals(id)
            select internet).FirstOrDefault();
        if(result != null)
           Request.CreateResponse(HttpStatusCode.OK, result);
    }
}

答案 3 :(得分:0)

您应该使用上下文类的Dispose(),因此请使用using构造:

using (var context = new InternetDbContext())
{    
    // your code here, try/catch is auto-generated by the compiler
}

答案 4 :(得分:0)

这是因为他们错了。不要相信别人的代码,特别是当它是在线教程的一部分时。

答案 5 :(得分:-1)

致电Dispose()或使用using处理DbContext但您 <。}

如果您想安全播放,请始终使用usingDispose(),但如果您希望更好地了解EF DbContext的实施情况,继续阅读。

长话短说,EF通常知道何时是关闭连接的时间,所以在多数的情况下,是否打电话Dispose()会做同样的结果并且不会t对内存使用或性能有任何影响,因为垃圾收集器将正确处理,大多数IDisposable类不同。

,有两个主要原因,您包裹using或致电Dispose() 专门 EF DbContext

首先是当有人从ObjectContext手动打开与DbContext的连接时,如果您没有拨打Dispose() / using,则可以保留打开的连接作为这些连接不会由EF自动管理。

第二个原因是您实例化的派生类DbContext可能会过度处理dispose的默认行为,例如将其他非托管资源的处置聚合到上下文的生命周期中,所以如果不正确的话处置后,它会让这些资源保持活力。

This article是必读的。