Common EF Core mistake: not using the difference between Tracking and No-Tracking Queries

What is this?

By default, a query is trackable, it means that if your query changes some properties of some entities and saves them, theses modifications will be repercuted on the database.

You query a product, you change his name and save the changes. The next time you will query this product his name will be the updated one. Great.

What is AsNoTracking?

The AsNoTracking method allows a query to not be trackable, so no changes will ever happen in the database, even if you call the SaveChanges method.

There is absolutely no sense in our previous example but what if you already know that your query won't modify the database?

What happens behind the scene?

Take this query:


return 
	myDbContext.Products
		.Where(x=>x.CategoryId == 1)
		.ToList()

EF Core will generate the query, send the query to the database provider that will run it then returns the results to EF Core that will parse and map the data, then EF Core will add the tracking fields it needs to work (basically it will add another field for all the entities fields to track the change, and some more for stuff like the indexes) then it will pass the results to your code than can continues to run.

What is the problem? Well, it hasn't but the step that consist for EF Core to add the tracking fields is a big one and can use massive memory space if it processes a lot of data, why doing this if you already know when you send the query that you won't update the database?

Let's see what happens if we now add the AsNoTracking to our query.

The query now looks like this:


return 
	myDbContext.Products
		.AsNoTracking()
		.Where(x=>x.CategoryId == 1)
		.ToList()

What happens now behind the scene? Exaclty the same that for the first query except that the tracking step is skipped:

Is there any difference for your code? There is absolutely no difference for your code except that the SaveChanges method won't have any effect now if your are using it, if you don't there is no difference for you.

Why caring about this?

What are the gains? Performance!

Non-tracked queries can run 7 or 8 times faster and use 4 or 5 less memories. If your queries manipulate a lot of data, that can be a massive gain.

Note two things:

October 19, 2023
  • Entity Framework Core
  • EF Core
  • No-tracking queries
  • Tracking queries