در Entity Framework زمانی که شما رکوردهایی را از دیتابیس میخوانید این رکوردها توسط ChangeTracker ردیابی میشوند. با استفاده از این قابلیت Entity Framework تمامی تغییرات بر روی موجودیت ها و پراپرتی ها را نگه میدارد. هر موجودیت در هر زمان دارای یکی از حالت های زیر است :

  • Added
  • Modified
  • Deleted
  • Unchanged
  • Detached

Unchanged : اول از همه, زمانی که رکوردی توسط Entity Framework از دیتابیس خوانده میشود در این وضعیت قرار دارد. در این وضعیت هیچ تغییری بر روی موجودیت و پراپرتی های آن اعمال نشده است.

using (var context = new Context())
{              
    var user = context.Users.Find(1);
    Console.WriteLine(context.Entry(user).State);// Unchanged
}

Added : این حالت برای زمانی است که شما یک موجودیت جدید بدون کلید را توسط متد Add یا Update به کانتکس اضافه کرده اید.

using (var context = new Context())
{              
    context.Users.Add(new Users() { FirstName = "Farhad", LastName = "Zamani" });
    context.ChangeTracker.Entries().ToList().ForEach(a => Console.WriteLine(a.Entity + " " + a.State));// Users Added
}

Modified : اگر مقدار یکی از پراپرتی های موجودیت خوانده شده از دیتابیس را تغییر دهید, موجودیت به این حالت منتقل میشود.

using (var context = new Context())
{              
    var user = context.Users.Find(1);
    user.Age = 21;
    Console.WriteLine(context.Entry(user).State);// Modified
}

Deleted : اگر هر موجودیتی توسط متدهای DbContext.Remove یا DbSet.Remove از کانتکس حذف شده باشد, موجودیت به عنوان حذف شده شناخته میشود.

using (var context = new Context())
{
    var user = context.Users.First();
    context.Users.Remove(user);
    Console.WriteLine(context.Entry(user).State);// Deleted
}

Detached : تمامی موجودیت های که خارج از محدوده Context ایجاده شده اند در این وضعیت قرار دارند.

var detachedUser = new Users() {  UserId = 1, Name = "Farhad"  };

using (var context = new Context())
{              
    Console.Write(context.Entry(detachedUser).State); //Detached
}

نکته مهم : هنگام خواندن داده ها از دیتابیس اگر هدف شما فقط نمایش اطلاعات به کاربر است از AsNoTracking استفاده کنید. زیرا تمامی رکوردهای خوانده شده از دیتابیس به صورت پیشفرض توسط ChangeTracker ردیابی میشوند و این کار باعث کندی در خواندن اطلاعات میشود. اما اگر شما رکوردهای دیتابیس را با استفاده از AsNoTracking بخوانید هیچ رکوردی ردیابی نمیشود و داده ها با سرعت بیستری بارگذاری میشوند به علاوه حافظه کمتری اشغال میشود. اما اگر تغییری در یکی از موجودیت ها ایجاد کنید ChangeTracker متوجه تغییرات اعمال شده نخواهد شد و تغییرات شما بعد از SaveChange اعمال نخواهند شد. اما میتوان با استفاده از متد Attach موجودیت را به ChangeTracker معرفی کنید و تغییرات اعمال شده را ثبت کنید.

var entity = context.Users.AsNoTracking().First();
entity.Name = "Farhad";
if (context.Entry(entity).State == EntityState.Detached)
    context.Attach(entity);

توجه داشته باشید در EntityFramework 6 هنگام استفاده از AsNoTracking ریلیشن ها بارگذاری نمیشود و باید با دستور Include ریلیشن های مورد نیاز را بارگذاری کنید.

Powered by Froala Editor