Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Aanbeveling
U kunt het voorbeeld van gebeurtenissen downloaden vanuit GitHub.
Met Entity Framework Core (EF Core) worden .NET-gebeurtenissen beschikbaar gesteld om als callbacks te fungeren wanneer bepaalde dingen plaatsvinden in de EF Core-code. Gebeurtenissen zijn eenvoudiger dan interceptors en maken flexibelere registratie mogelijk. Ze zijn echter strikt synchroon en kunnen daarom geen niet-blokkerende asynchrone I/O uitvoeren.
Gebeurtenissen worden geregistreerd per DbContext exemplaar. Gebruik een diagnostische listener om dezelfde informatie op te halen, maar voor alle DbContext-exemplaren in het proces.
Gebeurtenissen die door EF Core worden uitgelokt
De volgende gebeurtenissen worden gegenereerd door EF Core:
| Gebeurtenis | Wanneer deze wordt verhoogd |
|---|---|
| DbContext.SavingChanges | Aan het begin van SaveChanges of SaveChangesAsync |
| DbContext.SavedChanges | Aan het einde van een geslaagde SaveChanges of SaveChangesAsync |
| DbContext.SaveChangesFailed | Aan het einde van een mislukte SaveChanges of SaveChangesAsync |
| ChangeTracker.Tracked | Wanneer een entiteit wordt bijgehouden door de context |
| ChangeTracker.StateChanged | Wanneer een bijgehouden entiteit de status wijzigt |
Voorbeeld: wijzigingen van tijdstempelstatus
Elke entiteit die wordt bijgehouden door een DbContext heeft een EntityState. De status geeft bijvoorbeeld Added aan dat de entiteit wordt ingevoegd in de database.
In dit voorbeeld worden de Tracked en StateChanged gebeurtenissen gebruikt om te detecteren wanneer een entiteit de status wijzigt. Vervolgens wordt de entiteit gestempeld met de huidige tijd die aangeeft wanneer deze wijziging is opgetreden. Dit resulteert in tijdstempels die aangeven wanneer de entiteit is ingevoegd, verwijderd en/of voor het laatst is bijgewerkt.
De entiteitstypen in dit voorbeeld implementeren een interface waarmee de tijdstempeleigenschappen worden gedefinieerd:
public interface IHasTimestamps
{
DateTime? Added { get; set; }
DateTime? Deleted { get; set; }
DateTime? Modified { get; set; }
}
Een methode op dbContext van de toepassing kan vervolgens tijdstempels instellen voor elke entiteit die deze interface implementeert:
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;
}
}
}
Deze methode heeft de juiste signatuur om te gebruiken als een gebeurtenis-handler voor zowel de Tracked- als de StateChanged-gebeurtenissen. De handler is geregistreerd voor beide gebeurtenissen in de DbContext-constructor. Houd er rekening mee dat gebeurtenissen op elk gewenst moment aan een DbContext kunnen worden gekoppeld; dit is niet vereist in de contextconstructor.
public BlogsContext()
{
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
Beide gebeurtenissen zijn nodig omdat nieuwe entiteiten gebeurtenissen activeren Tracked wanneer ze voor het eerst worden bijgehouden.
StateChanged gebeurtenissen worden alleen geactiveerd voor entiteiten die de status wijzigen terwijl ze al worden bijgehouden.
Het voorbeeld voor dit voorbeeld bevat een eenvoudige consoletoepassing die wijzigingen aanbrengt in de blogdatabase:
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();
}
De uitvoer van deze code toont de statuswijzigingen en de tijdstempels die worden toegepast:
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