Let's assume a simple ASP.NET MVC controller:
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)
}
}
What exactly happens, if I forget about the using-statement? Will the context never expose? Will it leak memory? Is it really a deadly sin?
CodePudding user response:
This will leave an open database connection, as well as keep memory allocated for all tracked instances until garbage collection works out that the references are all not in use and actually releases them.
So if your Models table has 100k rows:
var db = new SomeDataContext(); // 1 connection from the connection pool when first query is run.
var models = db.Models.ToList(); // 100k loaded entities.
Testing this as a single user you're not going to see that much unless you start looking at your memory usage... Deploy that onto a web server that has 100 users that make concurrent requests and watch your web server grind itself into oblivion.
Also, avoid returning Entities to the view, project just the data you need into a ViewModel/DTO using Select()
or Automapper's ProjectTo()
. (don't use Automapper's Map()
) Not only does this avoid pitfalls like lazy-load hits for related data, but also produces more efficient / faster queries.
Always dispose of your DbContext instances. This means either use using
blocks or set up dependency injection to manage the lifetime scope of an injected DbContext, scoped to Per HTTP Request for web sites/services.