ISoftDeletable taşıyan her aggregate, silindiğinde DeletedAt/DeletedBy damgalanır ve sorgulardan otomatik gizlenir.
ISoftDeletable
EntityBase bu arayüzü taşır; alanlar ve IsDeleted() kontrolü buradan gelir:
DeletedAt != null ise. DeletedAt == null olan kayıtlar aktiftir.
Silme nasıl gerçekleşir
RepositoryRemove/DeleteAsync çağrısı entity’yi EntityState.Deleted’a alır; AuditInterceptor bunu yakalayıp soft-delete’e çevirir:
DELETE yerine UPDATE ... SET deleted_at = now, deleted_by = userId çalışır. Detaylar Audit Interceptor sayfasında.
Global query filter
OnModelCreating, ISoftDeletable uygulayan her entity tipine DeletedAt == null filtresini reflection ile otomatik ekler:
WHERE deleted_at IS NULL koşulunu taşır. Ardalis.Specification EF Core’un altındaki IQueryable’ı kullandığı için spec tabanlı sorgularda da filtre aktif kalır.
Pratik sonuç: provisioning, lookup ve uniqueness check akışları soft-deleted kayıtları görmez. Örneğin iptal edilmiş bir üyelik yeniden login olduğunda eski (silinmiş) kayıt görünmediği için yeni bir
Citizen oluşturulur.Silinmişleri görme — IgnoreQueryFilters
Audit raporlama gibi senaryolarda soft-deleted kayıtları dahil etmek için sorgu açıkça filtreyi devre dışı bırakır:Restore — geri alma
Soft-delete’i geri almakDeletedAt/DeletedBy’ı null yapmaktır. RolePermission bunu domain metoduyla yapar:
IgnoreQueryFilters() ile sorgulanır, sonra Restore() çağrılır.
Unique index sorunu ve partial index çözümü
Soft-delete, naif unique constraint’leri bozar: aynı(role_id, permission_id) çifti bir kez silinip yeniden eklenmek istendiğinde, silinmiş satır hâlâ tabloda durduğu için unique ihlali oluşur.
Çözüm, partial unique index’tir — yalnızca aktif (silinmemiş) satırlar için benzersizlik zorlanır:
CREATE UNIQUE INDEX ... WHERE deleted_at IS NULL üretir. Böylece:
- Aktif kayıtlar arasında çift benzersizdir.
- Soft-deleted kayıtlar index dışında kalır → aynı çift yeniden eklenebilir veya
Restore()ile geri alınabilir.
İlgili
Audit Interceptor
Deleted → Modified dönüşümünün kaynağı.
DbContext & Repository
Global query filter’ın OnModelCreating’de kurulması.
Migrations
Partial unique index’in migration’larda üretimi.
Data Genel Bakış
Katman rolü ve şemalar.