Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

6 performance tips for Entity Framework Core 7

By Joydip Kanjilal, Contributor, InfoWorld |Entity Framework Core (EF Core) is an open source ORM (object-relational mapping) framework that bridges the gap between the object model of your application and the data model of your database. EF Core makes life simpler by allowing you to work with the database using .NET objects, instead of having to write arcane data access code. In an earlier post here, we discussed five best practices to improve data access performance in EF Core. In this article, we’ll examine six more ways to improve EF Core performance. To work with the code examples provided below, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here.First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2022 is installed in your system, follow the steps outlined below to create a new .NET Core console application project in Visual Studio.We’ll use this project to examine six ways to improve EF Core performance in the sections below.It should be noted that EF Core uses lazy loading by default. With lazy loading, the related entities are loaded into the memory only when they are accessed. The benefit is that data aren’t loaded unless they are needed. However, lazy loading can be costly in terms of performance because multiple database queries may be required to load the data.To solve this problem, you should use eager loading in EF Core. Eager loading fetches your entities and related entities in a single query, reducing the number of round trips to the database. The following code snippet shows how eager loading can be used.{    public List GetEntitiesWithEagerLoading()    {        List entities = this.Set()            .Include(e => e.Books)            .ToList();        return entities;    }}You should use async code to improve the performance and responsiveness of your application. Below I’ll share a code example that shows how you can execute queries asynchronously in EF Core. First, consider the following two model classes:{    public int Id { get; set; }    public string FirstName { get; set; }    public string LastName { get; set; }    public List Books { get; set; }}public class Book{    public int Id { get; set; }    public string Title { get; set; }    public Author Author { get; set; }}In the code snippet that follows, we’ll create a custom data context class by extending the DbContext class of EF Core library.    {        protected readonly IConfiguration Configuration;        public DataContext(IConfiguration configuration)        {            Configuration = configuration;        }        protected override void OnConfiguring        (DbContextOptionsBuilder options)        {            options.UseInMemoryDatabase("AuthorDb");        }        public DbSet Authors { get; set; }        public DbSet Books { get; set; }    }Note that we're using an in-memory database here for simplicity. The following code snippet illustrates how you can use async code to update an entity in the database using EF Core.{    var dbModel = await this._context.Authors       .FirstOrDefaultAsync(e => e.Id == author.Id);       dbModel.Id = author.Id;       dbModel.FirstName = author.FirstName;       dbModel.LastName = author.LastName;       dbModel.Books = author.Books;       return await this._context.SaveChangesAsync();}The N+1 problem has been around since the early days of ORMs. In EF Core, this can occur when you’re trying to load data from two tables having a one-to-many or many-to-many relationship. For example, let’s say you’re loading author data from the Authors table and also book data from the Books table.Consider the following piece of code.{    author.Books.ForEach(b => b.Title.ToUpper());}Note that the outer foreach loop will fetch all authors using one query. This is the “1” in your N+1 queries. The inner foreach that fetches the books represents the “N” in your N+1 problem, because the inner foreach will be executed N times.To solve this problem, you should fetch the related data in advance (using eager loading) as part of the “1” query. In other words, you should include the book data in your initial query for the author data, as shown in the code snippet given below.    .Include(b => b.Books);foreach (var entity in entitiesQuery){   entity.Books.ForEach(b => b.Title.ToUpper());}By doing so, you reduce the number of round trips to the database from N+1 to just one. This is because by using Include, we enable eager loading. The outer query, i.e., the entitiesQuery, executes just once to load all the author records together with the related book data. Instead of making round trips to the database, the two foreach loops work on the available data in the memory.When you’re quering data in EF Core, use IQueryable in lieu of IEnumerable. When you use IQueryable, the SQL statements will be executed on the database server, where the data is stored. By contrast, if you use IEnumerable, all operations will be performed in the memory of the application server, requiring the data to be retrieved.The following code snippet shows how you can use IQueryable to query data.query = query.Where(e => e.Id == 5);query = query.OrderBy(e => e.Id);List entities = query.ToList();The default behavior of EF Core is to track objects retrieved from the database. Tracking is required when you want to update an entity with new data, but it is a costly operation when you’re dealing with large data sets. Hence, you can improve performance by disabling tracking when you won’t be modifying the entities.For read-only queries, i.e. when you want to retrieve entities without modifying them, you should use AsNoTracking to improve performance. The following code snippet illustrates how AsNoTracking can be used to disable tracking for an individual query in EF Core.    .FirstOrDefaultAsync(e => e.Id == author.Id);The code snippet given below can be used to retrieve entities directly from the database without loading them into the memory.{    public IQueryable GetAuthors()    {        return Set().AsNoTracking();    }}The default behavior of EF Core is to send individual update statements to the database when there is a batch of update statements to be executed. Naturally, multiple hits to the database entail a significant performance overhead. To change this behavior and optimize batch updates, you can take advantage of the UpdateRange() method as shown in the code snippet given below.    {        public void BatchUpdateAuthors(List authors)        {            var students = this.Authors.Where(a => a.Id >10).ToList();            this.UpdateRange(authors);            SaveChanges();        }        protected override void OnConfiguring        (DbContextOptionsBuilder options)        {            options.UseInMemoryDatabase("AuthorDb");        }        public DbSet Authors { get; set; }        public DbSet Books { get; set; }    }If you’re using EF Core 7 and beyond, you can use the ExecuteUpdate and ExecuteDelete methods to perform batch updates and eliminate multiple database hits. For example:We’ve examined several key strategies you can adopt to improve data access performance using EF Core. You should use a benchmarking tool such as BenchmarkDotNet to measure the performance of your queries after applying the changes described in this article. (See my article on BenchmarkDotNet here.) Additionally, you should fine-tune your database design, indexes, queries, and stored procedures to get maximum benefits.Performance should be a feature of your application. It is imperative that you keep performance in mind from the outset whenever you are building applications that use a lot of data.Next read this:Joydip Kanjilal is a Microsoft MVP in ASP.NET, as well as a speaker and author of several books and articles. He has more than 20 years of experience in IT including more than 16 years in Microsoft .NET and related technologies. Copyright © 2023 IDG Communications, Inc.Copyright © 2023 IDG Communications, Inc.



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

6 performance tips for Entity Framework Core 7

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×