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.
Estado | Valor | Descripción | Ejemplo SQL generado |
---|---|---|---|
Detached | 0 | No rastreado por el DbContext | Ninguno |
Unchanged | 1 | Existe en DB y no ha cambiado | Ninguno |
Added | 2 | Nuevo, se insertará al guardar | INSERT INTO... |
Modified | 3 | Existente con cambios pendientes | UPDATE... |
Deleted | 4 | Existente, se eliminará al guardar | DELETE 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;