Way back in 2012, I added a feature request to EF6 to allow us to define a context that will never track entities that it retrieves from the database.
(Support Read-Only Context or DbSet)
This is instead of having to add AsNoTracking to all of your queries if you have a DbContext you are using for read-only data. Or more importantly, if your DbContext is being used for data that’s going to be disconnected and therefore never tracked post-query. That means a Web API or service or a controller. Tracking can be expensive if you are retrieving a lot of data and have no plans to update it. And having to remember to add AsNoTracking to every query is a PIA.
I just discovered that this is possible with EF Core and I think it was even in the EF Core 1.0 release!
There is a ChangeTracker property called QueryTrackingBehavior that takes a QueryTrackingBehavior enum whose options are NoTracking and TrackAll.
There are plenty of places to use it, but the one I’m excited about is to place it directly in the constructor of a DbContext to make that context default to never track any entities.
public class BookContext : DbContext { public BooksReadOnlyContext() { ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } public DbSet<Book> Books {get;set;} etc ...
A quick test where I retrieved some books and the inspected the ChangeTracker.Entries returned 0, to show that this was doing what I’ve been dreaming of for over 5 years! Thanks EF team!
Console.WriteLine( $"Tracked Entities: {context.ChangeTracker.Entries().Count()}");
Another point to be aware of is that just as you have always been able to use the DbSet’s AsNoTracking method to turn off tracking for a particular query, you can now use AsTracking to turn on tracking for a particular query.