Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Conseil / Astuce
Vous pouvez télécharger l’exemple d’événements à partir de GitHub.
Entity Framework Core (EF Core) expose les événements .NET pour agir en tant que rappels lorsque certaines choses se produisent dans le code EF Core. Les événements sont plus simples que les intercepteurs et permettent une inscription plus flexible. Toutefois, ils sont synchronisés uniquement et ne peuvent donc pas effectuer d’E/S asynchrones non bloquantes.
Les événements sont inscrits par DbContext instance. Utilisez un écouteur de diagnostic pour obtenir les mêmes informations, mais pour toutes les instances DbContext dans le processus.
Événements déclenchés par EF Core
Les événements suivants sont déclenchés par EF Core :
| Événement | Lorsqu'il est soulevé |
|---|---|
| DbContext.SavingChanges | Au début de SaveChanges ou SaveChangesAsync |
| DbContext.SavedChanges | À la fin d’un événement réussi SaveChanges ou SaveChangesAsync |
| DbContext.SaveChangesFailed | À la fin d’un échec SaveChanges ou SaveChangesAsync |
| ChangeTracker.Tracked | Lorsqu’une entité est suivie par le contexte |
| ChangeTracker.StateChanged | Lorsqu’une entité suivie change d’état |
Exemple : Modifications de l’état d’horodatage
Chaque entité suivie par un DbContext a un EntityState. Par exemple, l’état Added indique que l’entité sera insérée dans la base de données.
Cet exemple utilise les événements Tracked et StateChanged pour détecter quand une entité change d’état. Il marque ensuite l’entité avec l’heure actuelle indiquant quand cette modification s’est produite. Cela entraîne des horodatages indiquant quand l’entité a été insérée, supprimée et/ou mise à jour la dernière fois.
Les types d’entités de cet exemple implémentent une interface qui définit les propriétés d’horodatage :
public interface IHasTimestamps
{
DateTime? Added { get; set; }
DateTime? Deleted { get; set; }
DateTime? Modified { get; set; }
}
Une méthode sur dbContext de l’application peut ensuite définir des horodatages pour n’importe quelle entité qui implémente cette interface :
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;
}
}
}
Cette méthode a la signature appropriée pour être utilisée comme gestionnaire d’événements pour les événements Tracked et StateChanged. Le gestionnaire est inscrit pour les deux événements dans le constructeur DbContext. Notez que les événements peuvent être attachés à un DbContext à tout moment ; il n’est pas nécessaire que cela se produise dans le constructeur de contexte.
public BlogsContext()
{
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
Les deux événements sont nécessaires, car de nouvelles entités déclenchent Tracked des événements lorsqu’elles sont suivies pour la première fois.
StateChanged les événements sont déclenchés uniquement pour les entités qui changent d’état pendant qu’elles sont déjà suivies.
L’exemple de cet exemple contient une application console simple qui apporte des modifications à la base de données 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 sortie de ce code montre les modifications d’état qui se produisent et les horodatages appliqués :
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