Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wskazówka
Przykładowe zdarzenia można pobrać z usługi GitHub.
Program Entity Framework Core (EF Core) udostępnia zdarzenia .NET, by pełnić rolę wywołań zwrotnych, gdy w kodzie EF Core występują pewne zdarzenia. Zdarzenia są prostsze niż przechwytywacze i pozwalają na bardziej elastyczną rejestrację. Jednak działają one tylko w trybie synchronicznym, a więc nie mogą wykonywać nieblokujących asynchronicznych operacji wejścia/wyjścia.
Zdarzenia są rejestrowane na DbContext wystąpienie. Użyj odbiornika diagnostycznego, aby uzyskać te same informacje, ale dla wszystkich wystąpień DbContext w procesie.
Zdarzenia zgłaszane przez program EF Core
Następujące zdarzenia są wywoływane przez program EF Core:
| Zdarzenie | Po podniesieniu |
|---|---|
| DbContext.SavingChanges | Na początku SaveChanges lub SaveChangesAsync |
| DbContext.SavedChanges | Na końcu udanego procesu SaveChanges lub SaveChangesAsync |
| DbContext.SaveChangesFailed | Na końcu nieudanej próby SaveChanges lub SaveChangesAsync |
| ChangeTracker.Tracked | Kiedy jednostka jest śledzona przez kontekst |
| ChangeTracker.StateChanged | Gdy śledzona jednostka zmienia swój stan |
Przykład: zmiany stanu znacznika czasu
Każda jednostka śledzona przez element DbContext ma element EntityState. Na przykład Added stan wskazuje, że jednostka zostanie wstawiona do bazy danych.
W tym przykładzie użyto zdarzeń Tracked i StateChanged do wykrywania, kiedy jednostka zmienia stan. Następnie oznacza jednostkę bieżącą godziną wskazującą, kiedy ta zmiana się wydarzyła. Spowoduje to znaczniki czasu wskazujące, kiedy jednostka została wstawiona, usunięta i/lub ostatnia aktualizacja.
Typy jednostek w tym przykładzie implementują interfejs definiujący właściwości znacznika czasu:
public interface IHasTimestamps
{
DateTime? Added { get; set; }
DateTime? Deleted { get; set; }
DateTime? Modified { get; set; }
}
Metoda w obiekcie DbContext aplikacji może następnie ustawić znaczniki czasu dla dowolnej jednostki, która implementuje ten interfejs:
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;
}
}
}
Ta metoda ma odpowiedni podpis do użycia jako program obsługi zarówno zdarzeń Tracked i StateChanged. Procedura obsługi jest rejestrowana dla obu zdarzeń w konstruktorze klasy DbContext. Należy pamiętać, że zdarzenia mogą być dołączane do obiektu DbContext w dowolnym momencie; nie jest wymagane, aby miało to miejsce w konstruktorze kontekstu.
public BlogsContext()
{
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
Oba zdarzenia są potrzebne, ponieważ nowe podmioty uruchamiają Tracked zdarzenia, gdy są po raz pierwszy śledzone.
StateChanged Zdarzenia są wyzwalane tylko dla jednostek, które zmieniają stan, gdy są już śledzone.
Przykład dla tego przykładu zawiera prostą aplikację konsolową, która wprowadza zmiany w bazie danych blogów:
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();
}
Dane wyjściowe z tego kodu pokazują zmiany stanu i zastosowane znaczniki czasu:
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