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, these modifications will be reflected in the database.

You query a product, you change its name and save the changes. The next time you query this product its 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.

That makes 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 scenes?

Take this query:


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

EF Core will generate the query, send it to the database provider that will run it then return the results to EF Core, which 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 every entity field to track the change, and some more for stuff like the indexes), then it will pass the results to your code, which can continue to run.

What is the problem? Well, there isn't one, but the step where EF Core adds the tracking fields is a big one and can use a massive amount of memory if it processes a lot of data. Why do 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 scenes? Exactly the same as 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 you are using it; if you don't, there is no difference for you.

Why care about this?

What are the gains? Performance!

Non-tracked queries can run 7 or 8 times faster and use 4 or 5 times less memory. 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