我们在WCF服务方法中使用Entity Framework与数据库进行通信,最近我们在服务代码上运行了代码审查工具。像往常一样,我们得到了许多审查建议和评论,其中许多评论建议处理Entity Framework的上下文对象。所以我的问题是,如果我在方法内部使用一个Entity Framework上下文对象,当我退出该方法时,GC不会清理该上下文对象吗?我们需要显式地处理上下文对象吗?
我们在WCF服务方法中使用Entity Framework与数据库进行通信,最近我们在服务代码上运行了代码审查工具。像往常一样,我们得到了许多审查建议和评论,其中许多评论建议处理Entity Framework的上下文对象。所以我的问题是,如果我在方法内部使用一个Entity Framework上下文对象,当我退出该方法时,GC不会清理该上下文对象吗?我们需要显式地处理上下文对象吗?
DbContext
实现了IDisposable
接口,因此你应该在使用完后手动释放它。DBContext
很可能属于此类别,因为底层数据库连接是非托管代码。DbContext
,但答案是 DbContext
受到与每个其他 IDisposable
相同的最佳实践的影响,原因也完全相同 - 因此大多数情况下都是通用答案。 - Dan PuzeyDbContext
,但您不知道何时操作会发生(正如我第二段开头所述),而且是的,您应该显式释放(正如我第一句所述)。回答的其余部分是背景和详细信息,以解释为什么这很重要(对于 任何 IDisposable
)。 DbContext
的具体细节并不特别相关于答案,因为它们不会改变答案(并且是黑盒子代码的实现细节) 。 - Dan Puzey我认为最好的方法是在using语句中编写代码。
using(var cx = new DbContext())
{
//your stuff here
}
所以它被自动处理掉了。
IDisposable
接口,当你使用完毕后明确地释放它是一个好习惯。尤其是当你不拥有该对象的实现时,你应将其视为黑盒子。此外,即使现在没有必要释放它,在未来也可能需要。IDisposable
接口——那么就应该释放它。List<Test> listT;
using (Model1 db = new Model1())
{
listT = db.Tests.ToList(); //ToList Evaluates
}
foreach (var a in listT)
{
Console.WriteLine(a.value);
}
IEnumerable<Test> listT1;
using (Model1 db = new Model1())
{
listT1 = db.Tests;
}
foreach (var a in listT1) //foreach evaluates (but at wrong time)
{
Console.WriteLine(a.value);
}
IEnumerable<Test> listT1;
Model1 db = new Model1();
listT1 = db.Tests;
db.Dispose();
foreach (var a in listT1) //foreach evaluates (but at wrong time)
{
Console.WriteLine(a.value);
}
IEnumerable<Test> listT1;
Model1 db = new Model1();
listT1 = db.Tests;
foreach (var a in listT1) //foreach evaluates (but at wrong time)
{
Console.WriteLine(a.value);
}
public class DataTools
{
private AppContext _context;
protected AppContext Context => _context ?? (_context = new AppContext());
}
pubic class YourApp : DataTools
{
public void DoLotsOfThings()
{
var = Context.SomeTable.Where(s => s.....);
var stuff = GetSomeThing();
foreach(){}
}
Public string GetSomething()
{
return Context.AnotherTable.First(s => s....).Value;
}
}