AsNoTracking چه میکند و چه زمانی باید استفاده شود؟
☆نشان کردنپاسخ کوتاه
Change Tracker را برای آن کوئری غیرفعال میکند؛ نتیجه سریعتر و سبکتر است اما موجودیتهای برگشتی قابل ذخیرهسازی نیستند.
پاسخ کامل
بهصورت پیشفرض EF Core هر موجودیتی را که از دیتابیس میخواند در Change Tracker
ثبت میکند تا بتواند در SaveChanges تغییرات را تشخیص دهد. این کار هزینه دارد:
حافظه بیشتر و یک مرحله Snapshot اضافه برای هر ردیف.
وقتی داده فقط برای نمایش خوانده میشود، این هزینه هدر میرود.
AsNoTracking() آن را حذف میکند و در کوئریهای بزرگ تفاوت محسوسی میسازد.
اگر کل برنامه شما عمدتاً فقطخواندنی است، میتوانید پیشفرض را عوض کنید:
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
مثال کد
// فقط نمایش — بدون Tracking
var products = await context.Products
.AsNoTracking()
.Where(p => p.IsActive)
.ToListAsync();
// نیاز به ویرایش — با Tracking
var product = await context.Products.FirstAsync(p => p.Id == id);
product.Price = newPrice;
await context.SaveChangesAsync();
نکته مهم
برای کوئریهایی که Navigation Property تکراری برمیگردانند، AsNoTrackingWithIdentityResolution() از ساختهشدن نمونههای تکراری جلوگیری میکند.
اشتباه رایج
❌ استفاده از AsNoTracking و بعد تلاش برای SaveChanges روی همان موجودیت — تغییرات تشخیص داده نمیشوند و بیصدا ذخیره نمیشوند.
