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.
So, to begin with, C# and Entity Framework
The article focuses on some of the breaking changes in the EF 8 preview
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.
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.
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();
}
To install EF 8 preview, you can follow these steps:
Alternatively, you can also use the Package Manager Console to install EF 8 preview. Here’s how:
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.
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 DbSet
s 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.
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