TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 548 subscribers
Post #238 84
وقتی موجودیت‌هایی را که برای حذف علامت‌گذاری شده‌اند پیدا کردیم، در یک حلقه آن‌ها را پیمایش کرده و وضعیتشان را به EntityState.Modified تغییر می‌دهیم. همچنین باید مقادیر مربوط به پراپرتی‌های IsDeleted و DeletedOnUtc را تنظیم کنید. این کار باعث می‌شود EF به جای عملیات DELETE، یک عملیات UPDATE ایجاد کند.
public sealed class SoftDeleteInterceptor : SaveChangesInterceptor
{
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
if (eventData.Context is null)
{
return base.SavingChangesAsync(
eventData, result, cancellationToken);
}

IEnumerable<EntityEntry<ISoftDeletable>> entries =
eventData
.Context
.ChangeTracker
.Entries<ISoftDeletable>()
.Where(e => e.State == EntityState.Deleted);
foreach (EntityEntry<ISoftDeletable> softDeletable in entries)
{
softDeletable.State = EntityState.Modified;
softDeletable.Entity.IsDeleted = true;
softDeletable.Entity.DeletedOnUtc = DateTime.UtcNow;
}

return base.SavingChangesAsync(eventData, result, cancellationToken);
}
}


این رویکرد تضمین می‌کند که تمام عملیات حذف در سراسر برنامه از سیاست حذف نرم پیروی می‌کنند.
شما باید SoftDeleteInterceptor را با تزریق وابستگی (dependency injection) ثبت کرده و آن را با ApplicationDbContext پیکربندی کنید.
services.AddSingleton<SoftDeleteInterceptor>();

services.AddDbContext<ApplicationDbContext>(
(sp, options) => options
.UseSqlServer(connectionString)
.AddInterceptors(
sp.GetRequiredService<SoftDeleteInterceptor>()));


فیلتر کردن خودکار داده‌های حذف نرم شده 🔍

برای اطمینان از اینکه رکوردهای حذف نرم شده به طور خودکار از کوئری‌ها حذف می‌شوند، می‌توانیم از فیلترهای کوئری سراسری (global query filters) در EF Core استفاده کنیم. ما می‌توانیم فیلترهای کوئری را با استفاده از متد OnModelCreating روی موجودیت‌ها اعمال کنیم تا رکوردهای علامت‌گذاری شده به عنوان حذف شده، به طور خودکار مستثنی شوند. این ویژگی نوشتن کوئری‌ها را به شدت ساده می‌کند.
در اینجا نحوه پیکربندی فیلتر کوئری حذف نرم آمده است:
public sealed class ApplicationDbContext(
DbContextOptions<UsersDbContext> options) : DbContext(options)
{
public DbSet<Review> Reviews { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Review>().HasQueryFilter(r => !r.IsDeleted);
}
}


یک محدودیت این است که شما نمی‌توانید بیش از یک فیلتر کوئری برای هر موجودیت پیکربندی کنید.
با این حال، گاهی اوقات لازم است که رکوردهای حذف نرم شده را به صراحت در کوئری‌ها لحاظ کنید. شما می‌توانید این کار را با استفاده از متد IgnoreQueryFilters انجام دهید.
dbContex.Reviews
.IgnoreQueryFilters()
.Where(r => r.ApartmentId == apartmentId)
.ToList();

کوئری‌های سریع‌تر با استفاده از ایندکس فیلتر شده (Filtered Index) 🚀


برای بهبود عملکرد کوئری، به ویژه در جداولی که تعداد زیادی رکورد حذف نرم شده دارند، می‌توانید از ایندکس‌های فیلتر شده (filtered indexes) استفاده کنید. یک ایندکس فیلتر شده فقط شامل رکوردهایی است که معیارهای مشخص شده را برآورده می‌کنند. این کار اندازه ایندکس را کاهش داده و زمان اجرای کوئری را برای عملیاتی که رکوردهای فیلتر شده را مستثنی می‌کنند، بهبود می‌بخشد. اکثر پایگاه داده‌های محبوب از ایندکس‌های فیلتر شده پشتیبانی می‌کنند.
در اینجا نحوه پیکربندی یک ایندکس فیلتر شده با EF Core آمده است:
public sealed class ApplicationDbContext(
DbContextOptions<UsersDbContext> options) : DbContext(options)
{
public DbSet<Review> Reviews { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Review>().HasQueryFilter(r => !r.IsDeleted);

modelBuilder.Entity<Review>()
.HasIndex(r => r.IsDeleted)
.HasFilter("IsDeleted = 0");
}
}
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →