Merhaba,
Bugün, .NET Core projelerinde kullanıcının gerçekleştirdiği CRUD işlemlerini takip etmek için bir Audit Log örneği oluşturacağız.
Audit Log uygulamak için, .NET Core proje bağlamında Context sınıfındaki SaveChanges() metodunu ezerek Create, Update ve Delete işlemlerini izleyebiliriz.
Haydi başlayalım!

Başlamadan Önce
Ayrıca daha fazla içeriğime ulaşmak için YouTube kanalımı ziyaret edebilirsiniz.
Örnek proje kodlarını doğrudan aşağıdaki bağlantıdan inceleyebilirsiniz:
GitHub – EmreKabali/CoreAuditLogExample
Audit Log Nasıl Uygulanır?
Audit Modeli Oluşturma
İlk olarak, veritabanındaki işlemleri saklayacak Audit modelimizi oluşturalım:
public class Audit
{
public int Id { get; set; }
public string UserId { get; set; }
public string Type { get; set; }
public string TableName { get; set; }
public DateTime DateTime { get; set; }
public string OldValues { get; set; }
public string NewValues { get; set; }
public string AffectedColumns { get; set; }
public string PrimaryKey { get; set; }
}
Bu model, ilerleyen aşamalarda yapılan değişiklikleri saklamak için kullanılacaktır.
Audit Servisi Oluşturma
Audit modelini oluştururken işlemleri tekrar etmemek için bir servis oluşturalım:
public class AuditEntry
{
public AuditEntry(EntityEntry entry)
{
Entry = entry;
}
public EntityEntry Entry { get; }
public string UserId { get; set; }
public string TableName { get; set; }
public Dictionary<string, object> KeyValues { get; } = new();
public Dictionary<string, object> OldValues { get; } = new();
public Dictionary<string, object> NewValues { get; } = new();
public AuditType AuditType { get; set; }
public List<string> ChangedColumns { get; } = new();
public Audit ToAudit()
{
return new Audit
{
UserId = UserId,
Type = AuditType.ToString(),
TableName = TableName,
DateTime = DateTime.Now,
PrimaryKey = JsonConvert.SerializeObject(KeyValues),
OldValues = OldValues.Count == 0 ? "null" : JsonConvert.SerializeObject(OldValues),
NewValues = NewValues.Count == 0 ? "null" : JsonConvert.SerializeObject(NewValues),
AffectedColumns = ChangedColumns.Count == 0 ? "null" : JsonConvert.SerializeObject(ChangedColumns)
};
}
}
Bu kodda EntityEntry sınıfı, EF Core tarafından sağlanmaktadır.
Context Sınıfında SaveChanges() Ezme
Uygulama için oluşturulan Context sınıfında, SaveChanges() metodunu ezerek Audit kayıtlarını oluşturacak mantığı ekleyelim.
Öncelikle BeforeSaveChanges() adında bir metot oluşturalım:
private void BeforeSaveChanges()
{
ChangeTracker.DetectChanges();
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State is EntityState.Detached or EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry)
{
TableName = entry.Entity.GetType().Name
};
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.AuditType = AuditType.Create;
auditEntry.NewValues[propertyName] = property.CurrentValue;
auditEntry.UserId = entry.Property("CreatedBy")?.CurrentValue?.ToString() ?? "Null";
break;
case EntityState.Deleted:
auditEntry.AuditType = AuditType.Delete;
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.UserId = entry.Property("LastModifiedBy")?.CurrentValue?.ToString() ?? "Null";
break;
case EntityState.Modified:
if (property.IsModified)
{
auditEntry.ChangedColumns.Add(propertyName);
auditEntry.AuditType = AuditType.Update;
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
auditEntry.UserId = entry.Property("LastModifiedBy")?.CurrentValue?.ToString() ?? "Null";
}
break;
}
}
}
foreach (var auditEntry in auditEntries)
{
AuditLogs.Add(auditEntry.ToAudit());
}
}
SaveChanges() Metodunu Ezme
public override int SaveChanges()
{
BeforeSaveChanges();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
BeforeSaveChanges();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
Sonuç
Tebrikler!
Bu işlemler başarıyla tamamlandığında, Audit tablosuna şu şekilde kayıtlar eklenmiş olacaktır:
Output:
| Id | UserId | Type | TableName | DateTime | OldValues | NewValues |
|----|--------|--------|-----------|----------|-----------|-----------|
| 1 | 12345 | Create | Orders | 2025-03-13 | null | {"Amount":100} |
Örnek projenin kaynak kodlarını aşağıdaki GitHub deposunda bulabilirsiniz:
GitHub – EmreKabali/CoreAuditLogExample
Umarım faydalı olmuştur!

Audit Log Oluşturma .Net Core