我了解各种教程以及定位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
?
答案 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
但您 <。}
如果您想安全播放,请始终使用using
或Dispose()
,但如果您希望更好地了解EF DbContext
的实施情况,继续阅读。
长话短说,EF通常知道何时是关闭连接的时间,所以在多数的情况下,是否打电话Dispose()
会做同样的结果并且不会t对内存使用或性能有任何影响,因为垃圾收集器将正确处理,与大多数IDisposable
类不同。
但,有两个主要原因,您应包裹using
或致电Dispose()
专门 EF DbContext
。
首先是当有人从ObjectContext
手动打开与DbContext
的连接时,如果您没有拨打Dispose()
/ using
,则可以保留打开的连接作为这些连接不会由EF自动管理。
第二个原因是您实例化的派生类DbContext
可能会过度处理dispose的默认行为,例如将其他非托管资源的处置聚合到上下文的生命周期中,所以如果不正确的话处置后,它会让这些资源保持活力。
This article是必读的。