Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Sugerencia
Puede descargar el ejemplo de eventos de GitHub.
Entity Framework Core (EF Core) expone eventos de .NET para que actúen como devoluciones de llamada cuando se producen ciertas cosas en el código de EF Core. Los eventos son más sencillos que los interceptores y permiten un registro más flexible. Sin embargo, solo se sincronizan y, por tanto, no pueden realizar E/S asincrónicas no bloqueantes.
Los eventos se registran por DbContext instancia. Use un escuchador de diagnóstico para obtener la misma información, pero para todas las instancias de DbContext del proceso.
Eventos generados por EF Core
EF Core genera los siguientes eventos:
| Evento | Cuando se levanta |
|---|---|
| DbContext.SavingChanges | Al principio de SaveChanges o SaveChangesAsync |
| DbContext.SavedChanges | Al final de una operación correcta SaveChanges o SaveChangesAsync |
| DbContext.SaveChangesFailed | Al final de un error SaveChanges o SaveChangesAsync |
| ChangeTracker.Tracked | Cuando el contexto realiza un seguimiento de una entidad |
| ChangeTracker.StateChanged | Cuando una entidad con seguimiento cambia su estado |
Ejemplo: cambios en el estado del registro de tiempo
Cada entidad de la que realiza un seguimiento dbContext tiene un EntityState. Por ejemplo, el Added estado indica que la entidad se insertará en la base de datos.
En este ejemplo se usan los Tracked eventos y StateChanged para detectar cuándo cambia el estado de una entidad. A continuación, marca la entidad con la hora actual que indica cuándo se produjo este cambio. Esto da como resultado marcas de tiempo que indican cuándo se insertó, eliminó o actualizó por última vez la entidad.
Los tipos de entidad de este ejemplo implementan una interfaz que define las propiedades de marca de tiempo:
public interface IHasTimestamps
{
DateTime? Added { get; set; }
DateTime? Deleted { get; set; }
DateTime? Modified { get; set; }
}
A continuación, un método de DbContext de la aplicación puede establecer marcas de tiempo para cualquier entidad que implemente esta interfaz:
private static void UpdateTimestamps(object sender, EntityEntryEventArgs e)
{
if (e.Entry.Entity is IHasTimestamps entityWithTimestamps)
{
switch (e.Entry.State)
{
case EntityState.Deleted:
entityWithTimestamps.Deleted = DateTime.UtcNow;
Console.WriteLine($"Stamped for delete: {e.Entry.Entity}");
break;
case EntityState.Modified:
entityWithTimestamps.Modified = DateTime.UtcNow;
Console.WriteLine($"Stamped for update: {e.Entry.Entity}");
break;
case EntityState.Added:
entityWithTimestamps.Added = DateTime.UtcNow;
Console.WriteLine($"Stamped for insert: {e.Entry.Entity}");
break;
}
}
}
Este método tiene la firma adecuada para usar como controlador de eventos para los Tracked eventos y StateChanged . El controlador se registra para ambos eventos en el constructor DbContext. Tenga en cuenta que los eventos se pueden adjuntar a dbContext en cualquier momento; no es necesario que esto suceda en el constructor de contexto.
public BlogsContext()
{
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
Ambos eventos son necesarios porque las nuevas entidades activan eventos Tracked cuando son rastreadas por primera vez.
StateChanged los eventos solo se disparan para las entidades que cambian de estado mientras ya están siendo rastreadas.
La muestra para este ejemplo contiene una aplicación de consola sencilla que realiza cambios en la base de datos de blogs.
using (var context = new BlogsContext())
{
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
context.Add(
new Blog
{
Id = 1,
Name = "EF Blog",
Posts = { new Post { Id = 1, Title = "EF Core 3.1!" }, new Post { Id = 2, Title = "EF Core 5.0!" } }
});
await context.SaveChangesAsync();
}
using (var context = new BlogsContext())
{
var blog = await context.Blogs.Include(e => e.Posts).SingleAsync();
blog.Name = "EF Core Blog";
context.Remove(blog.Posts.First());
blog.Posts.Add(new Post { Id = 3, Title = "EF Core 6.0!" });
await context.SaveChangesAsync();
}
La salida de este código muestra los cambios de estado que se producen y las marcas de tiempo que se aplican:
Stamped for insert: Blog 1 Added on: 10/15/2020 11:01:26 PM
Stamped for insert: Post 1 Added on: 10/15/2020 11:01:26 PM
Stamped for insert: Post 2 Added on: 10/15/2020 11:01:26 PM
Stamped for delete: Post 1 Added on: 10/15/2020 11:01:26 PM Deleted on: 10/15/2020 11:01:26 PM
Stamped for update: Blog 1 Added on: 10/15/2020 11:01:26 PM Modified on: 10/15/2020 11:01:26 PM
Stamped for insert: Post 3 Added on: 10/15/2020 11:01:26 PM