Aracılığıyla paylaş


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. StateChangedolaylar 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())
{
    context.Database.EnsureDeleted();
    context.Database.EnsureCreated();

    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!" } }
        });

    context.SaveChanges();
}

using (var context = new BlogsContext())
{
    var blog = context.Blogs.Include(e => e.Posts).Single();

    blog.Name = "EF Core Blog";
    context.Remove(blog.Posts.First());
    blog.Posts.Add(new Post { Id = 3, Title = "EF Core 6.0!" });

    context.SaveChanges();
}

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