How Lazy Loading Works in EF 8 Preview Release

Written by ssukhpinder | Published 2023/02/23
Tech Story Tags: lazy-loading | entity-framework | dotnet | dotnet-core | linq | csharp | mssql | software-development | web-monetization

TLDRLazy loading is a technique that defers the loading of related entities until they are needed. This can reduce the amount of memory used and improve performance. A "no-tracking query" is a query that retrieves data from the database without tracking any changes to the returned entities. Lazy loading can be helpful when dealing with large datasets.via the TL;DR App

The .NET framework has been an industry leader for more than two decades. With the upcoming release of .NET 8, Microsoft is introducing new features and enhancements to improve the development experience for .NET developers.

Prerequisites

  • Basic knowledge of OOPS concepts.
  • Any programming language knowledge.

So, to begin with, C# and Entity Framework

Learning Objectives

The article focuses on some of the breaking changes in the EF 8 preview

  • What is Lazy loading?
  • What are No-Tracking queries?
  • How to install the EF8 Preview edition?
  • How to add Lazy-loading for no-tracking queries in the EF8 preview?

Getting Started

Entity Framework (EF) is an object-relational mapper (ORM) that provides a set of tools to work with databases in an object-oriented way. One of EF's features is lazy loading, which allows loading related entities on demand rather than eagerly loading all of them at once. Lazy loading can improve performance and reduce memory usage by only loading the needed data. This article will discuss how to use lazy-loading for no-tracking queries in EF 8 preview release with code examples.

What is Lazy Loading?

Lazy loading is a technique that defers the loading of related entities until they are needed. In EF, this means that the associated entities are not loaded when the primary entity is retrieved from the database but instead loaded when they are accessed for the first time. This is done by creating a proxy object representing the related entity and loading the actual data when the representative object is accessed.

Lazy loading can be helpful when dealing with large datasets, as it allows you to load only the needed data rather than all the data simultaneously. This can reduce the amount of memory used and improve performance.

What are No-Tracking queries?

In Entity Framework (EF), a "no-tracking query" is a query that retrieves data from the database without tracking any changes to the returned entities.

When EF retrieves data from the database, it creates tracked entities by default. EF keeps track of any changes made to these entities, such as adding, updating, or deleting them. It can automatically generate SQL statements to persist these changes back to the database when necessary.

However, you may not need to track changes to the returned entities in some scenarios. For example, when retrieving large amounts of data that will not be modified, tracking the entities can be an unnecessary overhead that can slow down the query execution and consume more memory. You can use no-tracking queries to retrieve the data without creating tracked entities in such cases.

To create a no-tracking query, you can use the AsNoTracking method on a DbSet. Here's an example:

using (var context = new MyContext())
{
    var customers = context.Customers.AsNoTracking().ToList();
}

How to install EF 8 Preview edition?

To install EF 8 preview, you can follow these steps:

  1. Open your Visual Studio 2019 or later version and create a new .NET Core or .NET Framework project.
  2. Right-click on the project in the Solution Explorer and select “Manage NuGet Packages.”
  3. In the “Browse” tab, search for “Microsoft.EntityFrameworkCore” and select it from the search results.
  4. Check the “Include pre-release” checkbox, and select the version of EF 8 that you want to install from the drop-down list.
  5. Click the “Install” button to install EF 8 preview.

Alternatively, you can also use the Package Manager Console to install EF 8 preview. Here’s how:

  1. Open the Package Manager Console by selecting “Tools > NuGet Package Manager > Package Manager Console” from the Visual Studio menu.
  2. In the Package Manager Console, enter the following command to install the EF 8 preview:
Install-Package Microsoft.EntityFrameworkCore -Version 8.0.0-preview.1.23111.4 -Pre

Press Enter to execute the command. The package will be installed in your project.

It is important to note that EF 8 preview is a pre-release version, which means it is not a stable release and may contain bugs and breaking changes. Therefore, it is not recommended to use EF 8 preview in production environments. Instead, it should only be used for testing and experimentation purposes. It is also recommended to thoroughly review the EF 8 preview release notes and documentation to fully understand the new features and changes introduced in this version.

Implement Lazy Loading in EF 8

EF 8 is the latest version of Entity Framework, which is currently in preview release. It introduces several new features and improvements, including improvements to lazy loading. In EF 8, lazy loading is enabled by default for all navigation properties, meaning related entities will be loaded on demand when accessed.

However, lazy loading is not enabled by default when using no-tracking queries, which do not track changes made to the entities. This is because no-tracking queries do not create proxy objects required for lazy loading. To enable lazy loading for no-tracking queries in EF 8, you need to enable it using the explicitly UseLazyLoadingProxies() method.

Please find below the example of how to use lazy loading with no-tracking queries in EF 8:

using Microsoft.EntityFrameworkCore;

public class MyContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLazyLoadingProxies().UseSqlServer("connectionString");
    }
}

public class Order
{
    public int OrderId { get; set; }
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }
}

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

In this example, we have a MyContext class that inherits from DbContext and defines two DbSets for Order and Customer. The OnConfiguring method is overridden to configure the database connection and enable lazy loading proxies using the UseLazyLoadingProxies() method.

The Order class has a CustomerId property that is a foreign key to the Customer class, and a Customer property that is marked as virtual to enable lazy loading. The Customer class has a collection of Order objects that are also marked as virtual to allow lazy loading.

Now, let's see how to use lazy loading with no-tracking queries in practice. Suppose we want to retrieve a list of customers and their associated orders, but we only need to read the data and intend to keep it the same. We can use the AsNoTracking() method to disable change tracking, improve performance, and access the related orders using lazy loading.

var customers = context.Customers
.Include(c => c.Orders)
.AsNoTracking()
.ToList();

foreach (var customer in customers)
{
  Console.WriteLine(customer.Name);
  foreach (var order in customer.Orders)
  {
    Console.WriteLine(" " + order.OrderId);
  }
}

In this code, we use the `Include` method to eagerly load the related `Order` objects for each `Customer` and then use the `AsNoTracking` method to disable change tracking. We then iterate over the customers and their orders using lazy loading.

Note that lazy loading can cause performance issues if misused. Accessing related entities in a loop can result in a large number of database queries being executed, which can be slow. To avoid this, you can use the `Include` method to load related entities in a single query eagerly or use the `Load` method to load associated entities explicitly.

Conclusion

Lazy loading is a valuable technique for loading related entities on demand rather than eagerly loading them all simultaneously. In EF 8, lazy loading is enabled by default for all navigation properties but is not enabled by default for no-tracking queries. To allow lazy loading for no-tracking queries, you must explicitly enable it using the `UseLazyLoadingProxies()` method. However, it would be best to use lazy loading cautiously to avoid performance issues and consider using eager or explicit loading in some cases.


Also Published Here


Written by ssukhpinder | I'm Sukhpinder Singh, a passionate self-taught .Net developer from India.
Published by HackerNoon on 2023/02/23