entity-framework-estados-entidades

Entity States in Entity Framework

  • 3 min

In EF Core, each entity has a state that determines how it will interact with the database when SaveChanges() is called.

Entity Framework needs to know what has happened to each entity since it was loaded or created. For that, it uses an internal property called EntityState.

The state of an entity indicates whether EF should insert, update, delete, or simply ignore an entity when saving changes to the database.

StateValueDescriptionGenerated SQL Example
Detached0Not tracked by the DbContextNone
Unchanged1Exists in DB and has not changedNone
Added2New, will be inserted on saveINSERT INTO...
Modified3Existing with pending changesUPDATE...
Deleted4Existing, will be deleted on saveDELETE FROM...

How the change tracker works

The DbContext maintains a change tracker that monitors all associated entities. We can inspect it:

var changes = context.ChangeTracker.Entries()
    .Where(e => e.State != EntityState.Unchanged)
    .ToList();

For example,

var product = new Product { Name = "Laptop" }; // State: Detached

context.Products.Add(product); // State: Added

var productDB = await context.Products.FindAsync(1); // State: Unchanged
productDB.Price = 999; // State: Modified

context.Products.Remove(productDB); // State: Deleted

Automatic state management

Generally, we will let Entity Framework automatically track changes to the entities associated with the DbContext through the Change Tracker.

An entity in the Added state will be inserted into the database when SaveChanges() is called. Entity Framework will generate an INSERT SQL statement for this entity.

// Example: Create a new student
var newStudent = new Student { Name = "Ana López", Age = 20 };
context.Students.Add(newStudent);
// Now newStudent is in the Added state
context.SaveChanges(); // Generates an INSERT

Entities in the Unchanged state already exist in the database and have not been modified since they were retrieved. They do not generate any SQL operation in SaveChanges().

// Querying a student
var student = context.Students.Find(1);
// student is in the Unchanged state after being retrieved

An entity in the Modified state will be updated in the database with an UPDATE SQL statement when SaveChanges() is called.

// Modifying an existing student
var student = context.Students.Find(1);
student.Name = "Ana María López";
// Entity Framework automatically detects the change
context.SaveChanges(); // Generates an UPDATE

An entity in the Deleted state will be removed from the database using a DELETE SQL statement when SaveChanges() is called.

// Deleting a student
var student = context.Students.Find(1);
context.Students.Remove(student);
// student is now in the Deleted state
context.SaveChanges(); // Generates a DELETE

An entity in the Detached state is not being tracked by the Entity Framework context. This means that any changes to this entity will not be detected or automatically persisted.

// Creating a detached entity
var detachedStudent = new Student { Id = 1, Name = "Carlos" };
// detachedStudent is in the Detached state

Manual state manipulation

We can also manually change the state. This is not common but sometimes necessary for advanced operations.

context.Entry(product).State = EntityState.Modified;