如果我不小心没有处理 Entity Framework 上下文,会发生什么?
What happens, if I accidentally don't dispose the Entity Framework context?
让我们假设一个简单的 ASP.NET MVC 控制器:
public class SomeController : Controller
{
public ActionResult SomeAction()
{
var db = new SomeDataContext(); // without 'using' or 'await using'
var models = db.Models.ToList();
return this.View(models)
}
}
如果我忘记 using-statement 会发生什么?上下文永远不会暴露吗?它会泄漏内存吗?真的是死罪吗?
这将保留打开的数据库连接,并保持为所有跟踪实例分配的内存,直到垃圾收集发现所有引用均未使用并实际释放它们。
因此,如果您的模型 table 有 10 万行:
var db = new SomeDataContext(); // +1 connection from the connection pool when first query is run.
var models = db.Models.ToList(); // +100k loaded entities.
以单个用户的身份对此进行测试,除非您开始查看您的内存使用情况,否则您不会看到那么多...将其部署到拥有 100 多个用户并发请求并观看您的网络的 Web 服务器上服务器将自己磨灭。
此外,避免将实体返回到视图,使用 Select()
或 Automapper 的 ProjectTo()
将您需要的数据投影到 ViewModel/DTO 中。 (不要使用Automapper的Map()
)这不仅避免了相关数据的延迟加载命中等陷阱,而且还产生了更高效/更快的查询。
始终处理您的 DbContext 实例。这意味着要么使用 using
块,要么设置依赖注入来管理注入的 DbContext 的生命周期范围,范围为 Per HTTP Request for web sites/services.
让我们假设一个简单的 ASP.NET MVC 控制器:
public class SomeController : Controller
{
public ActionResult SomeAction()
{
var db = new SomeDataContext(); // without 'using' or 'await using'
var models = db.Models.ToList();
return this.View(models)
}
}
如果我忘记 using-statement 会发生什么?上下文永远不会暴露吗?它会泄漏内存吗?真的是死罪吗?
这将保留打开的数据库连接,并保持为所有跟踪实例分配的内存,直到垃圾收集发现所有引用均未使用并实际释放它们。
因此,如果您的模型 table 有 10 万行:
var db = new SomeDataContext(); // +1 connection from the connection pool when first query is run.
var models = db.Models.ToList(); // +100k loaded entities.
以单个用户的身份对此进行测试,除非您开始查看您的内存使用情况,否则您不会看到那么多...将其部署到拥有 100 多个用户并发请求并观看您的网络的 Web 服务器上服务器将自己磨灭。
此外,避免将实体返回到视图,使用 Select()
或 Automapper 的 ProjectTo()
将您需要的数据投影到 ViewModel/DTO 中。 (不要使用Automapper的Map()
)这不仅避免了相关数据的延迟加载命中等陷阱,而且还产生了更高效/更快的查询。
始终处理您的 DbContext 实例。这意味着要么使用 using
块,要么设置依赖注入来管理注入的 DbContext 的生命周期范围,范围为 Per HTTP Request for web sites/services.