Entity Framework core, as the most used .net core ORM (object-relational mapping) framework, simplify the developer’s life by managing its database access complexity.
However, as it usually happens, such simplification comes with a price. In most cases, the price is flexibility and performance.
1.Simplicity is a trap
Injecting the database context in the built-in IoC container is as quick as the following:
The TodoContext becomes then accessible from anywhere needed in you application, to create, read, update or delete any data from your database provider.
The issue arises quickly when you have a different need than responding to an Http request, a background worker for example:
Background job containing a memory leak
If you don’t have enough knowledge of ASP.NET core and of the behaviors of EFcore, the leak is hard to spot:
DBContext objects tracking: during the lifetime of the context, all the manipulated entities are kept and tracked by default in the context object.
Dependency Injection scope: Each http request triggers the creation of a scope to resolve dependencies from. At the end of the request, the scope and the related dependencies will be disposed.
In definitive, we are here creating a memory leak by using a context that will keep growing in size through the whole application lifetime
2. Easy solution
Once spotted, the leak is easy to fix: DBContext should have a short life span!
We have 2 solutions here, either configure the ORM to avoid tacking entities or manually reduce the context lifetime.
Our solution here is, for each loop, to request a new DBContext that will be disposed at the end of the current iteration.