How to detach entities in Entity Framework Core

By FoxLearn 2/3/2025 9:32:31 AM   24
Entity Framework (EF) Core is an open-source, object-relational mapper (ORM) that simplifies data access in your application.

It allows you to perform CRUD (create, read, update, and delete) operations using code, without needing to worry about how the data is stored in the underlying database. EF Core is the version of Entity Framework that runs on .NET Core.

EF Core provides methods to retrieve, add, modify, or delete entities, as well as traverse entity graphs. While these operations are straightforward in connected scenarios, there are times when you need to work with entities in a disconnected mode and still track the complete object graph. This is where methods like ChangeTracker.TrackGraph come in handy.

Installing EF Core NuGet Packages

To use EF Core in your project, you need to install the required NuGet packages.

If you’ve already set up an ASP.NET Core web application in Visual Studio 2022, follow these steps:

Right-click your project in the Solution Explorer and select Manage NuGet Packages, then search for and install the following packages:

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

Alternatively, you can install the packages through the NuGet Package Manager Console:

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

Tracking Changes to Entities in EF Core

Entity Framework Core, like ADO.NET, can operate in both connected and disconnected modes. The DbContext class tracks entities retrieved from the database. When you call SaveChanges, any changes made to those entities are persisted in the database. In most cases, entities are fetched using one DbContext instance, and updates or deletes are performed with another instance.

This is common in disconnected scenarios, such as web applications, where entities are retrieved, sent to the client, modified, and then sent back for persistence. The second DbContext instance needs to be aware of the entity’s state, whether it is new or already exists in the database.

EntityState Property in EF Core

EF Core uses the EntityState property to track changes to entities. You can manipulate the state of an entity using methods like Attach, Add, Entry, Update, or Remove.

For example, you may retrieve an entity, modify it, and then set its state to Modified when saving it:

using (var dataContext = new DemoContext())
{
    var employee = dataContext.Employees.Single(e => e.Id == 3);
    employee.Name = "John Doe";
    dataContext.SaveChanges();
}

In disconnected scenarios, you must manually set the entity’s state. This can be done using the EntityState property or methods like DbContext.Update() or DbContext.Attach().

Using the TrackGraph Method in EF Core

The TrackGraph method is particularly useful when working with disconnected entities. It allows EF Core to track entities that were originally retrieved by one DbContext instance but modified or persisted using a different instance. The TrackGraph method traverses the entity’s navigation properties to track all related entities.

For example, how you can use TrackGraph when handling a product entity and its related categories:

var dbContext = new DemoContext();
var product = new Product { Id = 1, Name = "New Product" };
var category = new Category { Id = 2, Name = "Electronics" };

// Assume the product and category were previously retrieved and modified in another context
dbContext.ChangeTracker.TrackGraph(product, p =>
{
    if (p.Entry.IsKeySet)
    {
        p.Entry.State = EntityState.Modified;  // If the entity has a key, mark it as modified
    }
    else
    {
        p.Entry.State = EntityState.Added;    // If there's no key, mark it as new
    }
});

In this example, the TrackGraph method is used to traverse the product and its related categories, checking if they should be added or marked as modified.

Displaying Entity State

To inspect the state of all entities being tracked by the context, you can log or display their states. Here’s an example of how to log the state and type of all entities in the context:

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

This approach helps when debugging or monitoring which entities are being tracked and their current states.

Best Practices for Handling Disconnected Entities

EF Core can only track one instance of an entity with a specific primary key. To avoid conflicts in disconnected scenarios, a common practice is to use a short-lived DbContext for each unit of work.

In a typical web application, entities are fetched, sent to the client, modified, and then returned to be saved.

Here’s an example where a customer entity is retrieved, modified by the client, and then sent back for persistence:

// Retrieve the customer entity in the first context
var customer = dbContext.Customers.Find(1);

// Send customer data to the client for modification (disconnected mode)

// On the client, modify the customer and return it
using (var newContext = new DemoContext())
{
    var modifiedCustomer = newContext.Customers.Find(1);
    modifiedCustomer.Name = "Jane Doe";
    newContext.SaveChanges();
}

In this example, the customer entity is first retrieved and modified on the client side. The modified entity is then brought back into a new DbContext instance and saved to the database.