How to work with disconnected entities in Entity Framework Core

Learn how you can track changes to entities while disconnected from the EF context in Entity Framework Core.

How to work with disconnected entities in Entity Framework Core
Marcin Wichary (CC BY 2.0)

Entity Framework is an open source, object-relational mapper (ORM) that simplifies data access in your application. It enables you to write code to perform CRUD (create, read, update, and delete) operations without having to know how the data is persisted in the underlying database. Entity Framework Core is the edition of Entity Framework that runs on .NET Core.

Entity Framework Core offers methods to retrieve entities from the data store, to add, change, or delete entities, and to traverse entity graphs. While these techniques function well in connected circumstances, you may often want to work in a disconnected mode and still trace the complete object graph. This is where the ChangeTracker.TrackGraph method comes into play.

This article discusses how we can use the ChangeTracker.TrackGraph method to work with disconnected entities in Entity Framework Core. To work with the code examples provided in this article, 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.

Create an ASP.NET Core Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core project in Visual Studio 2022. Following these steps will create a new ASP.NET Core Web API 6 project in Visual Studio 2022:

  1. Launch the Visual Studio 2022 IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  7. Click Next.
  8. In the “Additional Information” window shown next, select .NET 6.0 as the target framework from the drop-down list at the top. Leave the “Authentication Type” as “None” (default).
  9. Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are unchecked as we won’t be using any of those features here.
  10. Click Create.

This will create a new ASP.NET Core 6 Web API project in Visual Studio 2022. We’ll use this project in the subsequent sections of this article.

Install the Entity Framework Core NuGet packages

If you have successfully created an ASP.NET Core 6 web application project in Visual Studio 2022, the next thing you should do is add the necessary NuGet packages to your project. To do this, select the project in the Solution Explorer window, right-click and select “Manage NuGet Packages...” In the NuGet Package Manager window, search for the following packages, and install them.

  • Install-Package Microsoft.EntityFrameworkCore
  • Install-Package Microsoft.EntityFrameworkCore.Tools
  • Install-Package Microsoft.EntityFrameworkCore.SqlServer

Alternatively, you can install the package via the NuGet Package Manager Console as shown below.

PM> Install-Package Microsoft.EntityFrameworkCore
PM> Install-Package Microsoft.EntityFrameworkCore.Tools
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer

Track changes to an entity in Entity Framework Core

ADO.NET can work in two different modes – connected and disconnected. Because Entity Framework Core is built on top of ADO.NET, it also supports both connected and disconnected modes of operation.

In Entity Framework Core, the DbContext instances can be used to track entities that are retrieved from the database. When the SaveChanges method is called, any modifications to these entities are recognized, and the database is updated appropriately. However, read operations on the entities are usually performed with one data context instance while a different data context instance is used to add, update, or delete the entity.

This separation is common in “disconnected” contexts, such as in web applications, where entities are searched, sent to the client, updated, returned in a request, and later persisted to the database. The second data context instance should know if the entities are new or if they are already available.

The EntityState property in Entity Framework Core

Entity Framework Core takes advantage of a property called State to keep a track of changes to an entity. This property is available on all entities and is of type EntityState. Changes to this property occur when you use methods such as Attach, Add, Entry, Update, or Remove.

The following code snippet illustrates how you can update an entity in the data store.

using (var dataContext = new DemoContext())
    var product = dataContext.Products.Single(p => p.Id == 7);
    product.Name = "Lenovo";
    product.Category = "Laptop";

Note that when you’re working with Entity Framework Core in disconnected mode, you must explicitly specify the entity that has changed. To do this, you can set the EntityState property we just discussed or use the DbContext.Update or DbContext.Attach method.

Use the TrackGraph method in Entity Framework Core

The TrackGraph method is used in disconnected scenarios in which the entities are fetched from the data store with one instance of the context, and changes to the entities are persisted in the data store with another instance of the context. The TrackGraph method traverses an entity’s navigation attributes to monitor all entities that are accessible, provided that the entity has not been tracked earlier.

The code snippet given below shows how you can use the TrackGraph method.

var dbContext = new DemoContext();
  dbContext.ChangeTracker.TrackGraph(product, p => {
  if (p.Entry.IsKeySet)
       p.Entry.State = EntityState.Unchanged;
       p.Entry.State = EntityState.Added;

In this example, if an entity has a key associated with it, then the entity is unchanged. By contrast, if a key is not associated with the entity, then it is obvious that the entity has been added.

The following code snippet illustrates how you can display the state and type of all entities that are a part of the data context.

foreach (var entity in dbContext.ChangeTracker.Entries())
    _logger.LogInformation("Entity: {0}, State: {1}",
    entity.Entity.GetType().Name, entity.State.ToString());

Entity Framework Core can track only one instance of an entity with a primary key. The best possible way to handle this downside is to use a short-lived context for each unit of work, where the context begins empty, has entities connected to it, and stores those entities. Eventually, when the unit of work is completed, the context is disposed of and deleted.

Copyright © 2022 IDG Communications, Inc.