entity-framework-estados-entidades

Estados de entidades en Entity Framework

  • 3 min

En EF Core, cada entidad tiene un estado que determina cómo interactuará con la base de datos cuando se llame a SaveChanges().

Entity Framework necesita saber qué ha pasado con cada entidad desde que fue cargada o creada. Para eso, usa una propiedad interna llamada EntityState.

El estado de una entidad indica si EF debe insertar, actualizar, eliminar o simplemente ignorar una entidad al guardar los cambios en la base de datos.

EstadoValorDescripciónEjemplo SQL generado
Detached0No rastreado por el DbContextNinguno
Unchanged1Existe en DB y no ha cambiadoNinguno
Added2Nuevo, se insertará al guardarINSERT INTO...
Modified3Existente con cambios pendientesUPDATE...
Deleted4Existente, se eliminará al guardarDELETE FROM...

Cómo funciona el change tracker

El DbContext mantiene un rastreador de cambios que supervisa todas las entidades asociadas. Podemos inspeccionarlo:

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

Por ejemplo,

var producto = new Producto { Nombre = "Laptop" }; // Estado: Detached

context.Productos.Add(producto); // Estado: Added

var productoDB = await context.Productos.FindAsync(1); // Estado: Unchanged
productoDB.Precio = 999; // Estado: Modified

context.Productos.Remove(productoDB); // Estado: Deleted

Gestión automática de estados

Generalmente, dejaremos que Entity Framework rastree automáticamente los cambios en las entidades asociadas al DbContext mediante el Change Tracker.

Una entidad en estado Added será insertada en la base de datos cuando se llame a SaveChanges(). Entity Framework generará una sentencia SQL INSERT para esta entidad.

// Ejemplo: Crear un nuevo estudiante
var nuevoEstudiante = new Estudiante { Nombre = "Ana López", Edad = 20 };
context.Estudiantes.Add(nuevoEstudiante);
// Ahora nuevoEstudiante está en estado Added
context.SaveChanges(); // Genera un INSERT

Las entidades en estado Unchanged ya existen en la base de datos y no han sido modificadas desde que se recuperaron. No generan ninguna operación SQL en SaveChanges().

// Consultando un estudiante
var estudiante = context.Estudiantes.Find(1);
// estudiante está en estado Unchanged tras ser recuperado

Una entidad en estado Modified será actualizada en la base de datos mediante una sentencia SQL UPDATE cuando se llame a SaveChanges().

// Modificando un estudiante existente
var estudiante = context.Estudiantes.Find(1);
estudiante.Nombre = "Ana María López";
// Entity Framework detecta el cambio automáticamente
context.SaveChanges(); // Genera un UPDATE

Una entidad en estado Deleted será eliminada de la base de datos utilizando una sentencia SQL DELETE cuando se llame a SaveChanges().

// Eliminando un estudiante
var estudiante = context.Estudiantes.Find(1);
context.Estudiantes.Remove(estudiante);
// estudiante ahora está en estado Deleted
context.SaveChanges(); // Genera un DELETE

Una entidad en estado Detached no está siendo rastreada por el contexto de Entity Framework. Esto significa que cualquier cambio en esta entidad no será detectado ni persistido automáticamente.

// Creando una entidad desvinculada
var estudianteDesvinculado = new Estudiante { Id = 1, Nombre = "Carlos" };
// estudianteDesvinculado está en estado Detached

Manipulación manual de estados

También podemos modificar manualmente el estado. No es lo habitual pero a veces es necesario para operaciones avanzadas.

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