Entity Framework Core Entity Framework Core - As No Tracking
(This page is currently in draft mode. The final content should be available within a few days.)
What is the Entity Framework Core AsNoTracking method?
The AsNoTracking()
method make the LINQ query to return entities but without added them in the ChangeTracker
. So those entities are not tracked and are known as Disconnected Entities
.
// Simple example with Where clause
Performance Comparison
Not adding entities in the Change Tracker come with some performance enhancement for the current query but also for future queries that will be performed from the same context.
Always remember, more the ChangeTracker
contains entities, slower it dramatically becomes.
Without AsNoTracking With AsNoTracking
10
100
1000
5000
Try it
When should I use AsNoTracking?
Honestly, if the ChangeTracker
contains or will contains only a few hundreds of entities or less, it simply doesn’t matter.
The performance improvement doesn’t worth all benefits which come with the ChangeTracker
or simply the trouble to ask the question to yourself if you should use the AsNoTracking
method or not.
However, if you return a large amount of entities, then you think about using the AsNoTracking
method whenever you do a read operation to disconnect those entities.
FAQ
- What
- How
- How AsNoTracking is different from AutoDetectChangesEnabled?
- How to use AsNoTracking and Attach an entity?
- How to use AsNoTracking and Delete an entity?
- How to use AsNoTracking and Insert an entity?
- How to use AsNoTracking and Update an entity?
- How to use AsNoTracking by default/global?
- How to use AsNoTracking with Anonymous Type?
- How to use AsNoTracking with Find?
- How to use AsNoTracking with FromSql?
- How to use AsNoTracking with FromSqlRaw?
- How to use AsNoTracking with FromSqlRawInterpolated?
- How to use AsNoTracking with Include?
- How to use AsNoTracking with Join?
- How to use AsNoTracking with Lazy Loading?
- How to use AsNoTracking with LINQ? Before or After Where?
- How to use AsNoTracking with Mock?
- How to use AsNoTracking with Projection?
- How to use AsNoTracking with RepositoryPattern?
- How to use AsNoTracking with SaveChanges?
- How to use AsNoTracking with Stored Procedure?
- Why
What AsNoTracking PROS & CONS?
Pros
- Improved performance over regular LINQ queries.
- Fully materialized objects.
- Simplest to write with syntax built into the programming language.
- Improve performance of future tracked queries.
Cons
- Not suitable for CUD operations.
- Certain technical restrictions, such as: Patterns using DefaultIfEmpty for OUTER JOIN queries result in more complex queries than simple OUTER JOIN statements in Entity SQL.
- Doesn’t associate related entities already existing in the Change Tracker
- You still can’t use LIKE with general pattern matching.
What AsNoTracking do under the hood?
Basically, the tracking and no tracking queries does the same except the part from the Change Tracker.
If you query which have related item already loaded in the ChangeTracker
, if the query is tracked, the ChangeTracker
will automatically set the navigation properties of those entities. However, if they are not tracked, the ChangeTracker
will do nothing.
How AsNoTracking is different from AutoDetectChangesEnabled?
They are totally different!
The AsNoTracking
method return disconnected entities. The performance is improved when querying entities.
The AutoDetectChangesEnabled
doesn’t automatically check if a modification has been made on connected entities. The performance is improved when saving entities.
So both behavior are completely different.
How to use AsNoTracking and Attach an entity?
In Entity Framework Core, when doing a LINQ query with the AsNoTracking
method, all entities are not part of the ChangeTracker
.
So, if you want to delete or update an entity, you need first to Attach
it to the context and change the EntityState
to Modified or Deleted.
// Example (Modified + Deleted)
NOTE: When performing an update, Entity Framework Core doesn’t know about initial value. Therefore, all properties will be considered as modified.
How to use AsNoTracking and Delete an entity?
In Entity Framework Core, when doing a LINQ query with the AsNoTracking
method, all entities are not part of the ChangeTracker
.
So, if you want to delete an entity, you need first to Attach
it to the context and change the EntityState
to Deleted.
// Example (Deleted)
How to use AsNoTracking and Insert an entity?
In Entity Framework Core, when doing a LINQ query with the AsNoTracking
method, all entities are not part of the ChangeTracker
.
Usually, trying to insert a disconnected entity doesn’t make sense as the entity already exists in the database but in some case, you want to insert it in a different database which now make sense.
// Example (Inserted)
How to use AsNoTracking and Update an entity?
In Entity Framework Core, when doing a LINQ query with the AsNoTracking
method, all entities are not part of the ChangeTracker
.
So, if you want to update an entity, you need first to Attach
it to the context and change the EntityState
to Modified
// Example (Modified)
NOTE: When performing an update, Entity Framework Core doesn’t know about initial value. Therefore, all properties will be considered as modified.
How to use AsNoTracking by default/global?
You can globally disable the tracking by setting the ChangeTracker.QueryTrackingBehavior
to QueryTrackingBehavior.NoTracking
.
// context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
How to use AsNoTracking with Anonymous Type?
In Entity Framework Core, if you make a LINQ Query and return anonymous entities, the anonymous entities is already not tracked. So, you don’t have to use the AsNoTracking
method.
It will not make sense to track those entities as there is no way to save it back to the database.
How to use AsNoTracking with Find?
This scenario usually doesn’t make sense as the goal of the Find
method is to return the entity from the ChangeTracker
if it has been already loaded.
Some people recommend to use the Find method and detach the entity, but it doesn’t make sense either and can cause some unexpected behavior as this entity will not be longer tracker, nor saved if there is a modification. (ref: https://stackoverflow.com/a/46223929/5619143)
How to use AsNoTracking with FromSql?
You can apply the AsNoTracking
method with FromSql
in the same way you do it with LINQ query.
// Example (FromSql)
How to use AsNoTracking with FromSqlRaw?
You can apply the AsNoTracking
method with FromSqlRaw
in the same way you do it with LINQ query.
// Example (FromSqlRaw)
How to use AsNoTracking with FromSqlRawInterpolated?
You can apply the AsNoTracking
method with FromSqlRawInterpolated
in the same way you do it with LINQ query.
// Example (FromSqlInterpolated)
How to use AsNoTracking with Include?
You can apply the AsNoTracking
method with Include
as you normally do it with LINQ query.
All entities returned will not be tracked which include parents and childs.
// Example (parent + child)
How to use AsNoTracking with Join?
How to use AsNoTracking with Lazy Loading?
How to use AsNoTracking with LINQ? Before or After Where?
It doesn’t really matter where you call the AsNoTracking
. It can be at the start, in middle or at the end before calling an immediate method such as ToList()
.
In all cases, the same behavior will happen. All entities will not part of the ChangeTracker
.
However, we recommend you to put it at the end before the immediate method for consistence reason.
// Example (re-use the first example)
How to use AsNoTracking with Mock?
TBD, we don't know either!
How to use AsNoTracking with Projection?
In Entity Framework Core, if you make a LINQ Query and return a projection, the projection is already not tracked. So, you don’t have to use the AsNoTracking
method.
How to use AsNoTracking with RepositoryPattern?
TODO: We must read about repository pattern
How to use AsNoTracking with SaveChanges?
In Entity Framework Core, when doing a LINQ query with the AsNoTracking
method, all entities are not part of the ChangeTracker
.
So, if you want to use SaveChanges to delete or update an entity, you need first to Attach
it to the context and change the EntityState
to Modified or Deleted.
// Example (Modified + Deleted)
NOTE: When performing an update, Entity Framework Core doesn’t know about initial value. Therefore, all properties will be considered as modified.
How to use AsNoTracking with Stored Procedure?
You can apply the AsNoTracking
method with Stored Procedure
in the same way you do it with LINQ query.
// Example (Stored Procedure)
Why (Problem / Cause / Issue)
TODO
Why AsNoTracking is slow?
TODO
Why AsNoTracking is not working?
TODO
Why AsNoTracking throw an identity issue?
TODO