EF Core'da .NET Olayları
Bahşiş
Olay örneğini GitHub'dan indirebilirsiniz.
Entity Framework Core (EF Core), EF Core kodunda bazı şeyler gerçekleştiğinde geri çağırma görevi görmesi için .NET olaylarını kullanıma sunar. Olaylar, kesicilerden daha basittir ve daha esnek kayıt sağlar. Öte yandan bunlar yalnızca eşitlenir ve bu nedenle engelleyici olmayan zaman uyumsuz G/Ç gerçekleştiremez.
Olaylar örnek başına DbContext
kaydedilir. İşlemdeki tüm DbContext örneklerine ilişkin olarak aynı bilgileri almak için tanılama dinleyicisi kullanın.
EF Core tarafından tetiklenen olaylar
Aşağıdaki olaylar EF Core tarafından oluşturulur:
Olay | Yükseltildiğinde |
---|---|
DbContext.SavingChanges | veya'ın SaveChanges başında SaveChangesAsync |
DbContext.SavedChanges | Başarılı SaveChanges bir veya SaveChangesAsync |
DbContext.SaveChangesFailed | Başarısız SaveChanges olan veya SaveChangesAsync |
ChangeTracker.Tracked | Bir varlık bağlam tarafından izlendiğinde |
ChangeTracker.StateChanged | İzlenen varlık durumunu değiştirdiğinde |
Örnek: Zaman damgası durumu değişiklikleri
DbContext tarafından izlenen her varlığın bir EntityStatevardır. Örneğin, durum varlığın Added
veritabanına eklendiğini gösterir.
Bu örnekte, bir varlığın Tracked durumu değiştiğinde algılamak için ve StateChanged olayları kullanılır. Ardından varlığı, bu değişikliğin ne zaman gerçekleştiğini belirten geçerli saatle damgalar. Bu, varlığın ne zaman eklendiğini, silindiğini ve/veya son güncelleştirildiğini gösteren zaman damgalarıyla sonuçlanır.
Bu örnekteki varlık türleri zaman damgası özelliklerini tanımlayan bir arabirim uygular:
public interface IHasTimestamps
{
DateTime? Added { get; set; }
DateTime? Deleted { get; set; }
DateTime? Modified { get; set; }
}
Uygulamanın DbContext üzerindeki bir yöntem daha sonra bu arabirimi uygulayan herhangi bir varlık için zaman damgaları ayarlayabilir:
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;
}
}
}
Bu yöntem, hem hem StateChanged
de olayları için olay işleyicisi olarak kullanılacak uygun imzaya Tracked
sahiptir. İşleyici, DbContext oluşturucusunda her iki olay için de kaydedilir. Olayların herhangi bir zamanda dbContext'e eklenebileceğini unutmayın; bunun bağlam oluşturucusunda gerçekleşmesi gerekli değildir.
public BlogsContext()
{
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
Yeni varlıklar ilk izlendiklerinde olayları tetiklediğinden Tracked
her iki olay da gereklidir. StateChanged
olaylar yalnızca zaten izlenirken durumu değiştiren varlıklar için tetiklenir.
Bu örneğe ilişkin örnek, blog veritabanında değişiklik yapan basit bir konsol uygulaması içerir:
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();
}
Bu kodun çıktısı, gerçekleşen durum değişikliklerini ve uygulanan zaman damgalarını gösterir:
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