Hi, developers!
Today, let’s talk about how we can improve performance in .NET applications via AsNoTracking the method from Entity Framework.
Requests from DB can be tracked or untracked. By default, all queries that return model objects from DB are trackable (unless you changed default behaviour with AutoDetectChangesEnabled
property, we will talk about in a minute).
When the data context retrieves data from the database, the Entity Framework places the retrieved objects in the cache and monitors changes that occur to those objects until it uses the SaveChanges()
or SaveChangesAsync()
method, which commits any changes to the database. But we don’t always need to track changes. For example, we just need to display data for viewing.
To prevent the data from being cached, the AsNoTracking()
method is used. When AsNoTracking()
is applied, the data returned from the request is not cached, that is, the request becomes untracked. This means that the Entity Framework does not perform any additional processing and does not allocate additional space for storing objects retаrieved from the database. And therefore, such queries are faster.
Now let’s get down to practice 🙂
Let’s say we have the following models and data context:
using Microsoft.EntityFrameworkCore; namespace AsNoTrackinsExample { public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } public class AppDbContext : DbContext { public DbSet Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("yoursConnectionString"); } } }
And I’ve inserted in the database 6828 rows for Users
table.
Next step — to get data from DB without AsNoTracking
and with AsNoTracking
and compare performance. For comparing I use Benchmark.
using System.Collections.Generic; using System.Linq; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; using Microsoft.EntityFrameworkCore; namespace AsNoTrackinsExample { class Program { static void Main(string[] args) { var summary = BenchmarkRunner.Run(); } } [MemoryDiagnoser] public class MemoryBenchmarkerDemo { [Benchmark] public List GetUsers() { using (AppDbContext db = new AppDbContext()) { return db.Users.ToList(); } } [Benchmark] public List GetUsersWithNoTracking() { using (AppDbContext db = new AppDbContext()) { return db.Users.AsNoTracking().ToList(); } } } }
Wow! We can see an advantage in both speed of execution and memory usage. Mostly the differences will be noticeable on large amounts of data.
But remember, that we can not update any item or collection that we received with AsNoTracking
, because Entity Framework does not store these objects in the cache.
using System.Linq; using Microsoft.EntityFrameworkCore; namespace AsNoTrackinsExample { class Program { static void Main(string[] args) { using (AppDbContext db = new AppDbContext()) { var user = db.Users.AsNoTracking().FirstOrDefault(); user.Age = 22; db.SaveChanges(); // Age will not be updated } } } }
In addition to using the AsNoTracking
method, you can disable tracking in general for the context object.
To do this, set the false value for the db.ChangeTracker.AutoDetectChangesEnabled
property:
using Microsoft.EntityFrameworkCore; namespace AsNoTrackinsExample { class Program { static void Main(string[] args) { using (AppDbContext db = new AppDbContext()) { db.ChangeTracker.AutoDetectChangesEnabled = false; ... } } } }
In general, through the ChangeTracker
property, we can manage the tracking of an object and receive a variety of information. For example, we can find out how many objects are currently being tracked:
using System.Linq; namespace AsNoTrackinsExample { class Program { static void Main(string[] args) { using (AppDbContext db = new AppDbContext()) { var users = db.Users.ToList(); int count = db.ChangeTracker.Entries().Count(); } } } }
- When should you use
AsNoTracking
? If you just need to display data for display without the need for further updating, then this is the case when we can useAsNoTracking
.
Happy coding 😉
Stas Z.
Ukraine, for one, is one of the foremost helpful goals for outsourcing. In case you want to hire skilled local developers, don’t hesitate to reach out to Honeycomb Software. Our team supports companies of all scales with software development, testing, design, and product support. We would be happy to collaborate with you and to help you with your project! Just drop a line 🙂