در برنامه نویسی پایگاه داده، یک تغییر در پایگاه داده در برگیرنده درج داده تازه و بروز رسانی و پاک کردن یک داده است. در نوشته های پیشین برخی از متدهای کلاس DbSet مانند ()Add و ()AddRange و ()Remove را آموزش دادیم که به شیوه خودکار تغییرها را ردیابی و بر روی پایگاه داده اعمال می کنند.

متد های ()Find و ()SaveChanges دو متد دیگر کلاس DbSet هستند. همچنین متد دیگری به نام ()RemoveRange هست که فهرستی از سطرها را پاک می کند.

غیر فعال کردن پیگیری خودکار تغییرها

در کد زیر نمونه ای از کلاس Context به نام BloggingContext ساخته شده است و سپس درون بدنه عبارت using، به کمک نمونه کلاس BloggingContext به ویزگی AutoDetectChangeEnabled از کلاس Configuration دسترسی پیدا کرده ایم و مقدار آن را برابر flase تعیین کرده ایم که به معنی غیر فعال شدن ردیابی و تشخیص خودکار تغییرها در این Context است که از کلاس BloggingContext ساخته شده است.

گمان کنید همانند کد بالا می خواهید یکی از متدهای گفته شده را درون یک حلقه انجام دهید، بنابراین شاید این، تا اندازه ای بر کارایی انجام برنامه شما تاثیر بگذارد، بنابراین بهتر است در یک عبارت try…finally، نخست ویژگی AutoDetectChangeEnabled را غیر فعال کرده و پس از پایان یافتن حلقه، آن را درون عبارت finally فعال کنید.

وضعیت موجودیت در Entity Framework

Entity Framework یک ORM فراگیر و ساده و با ویژگی بسیاری است که برنامه نویسی سی شارپ را برای هم کنشی (تعامل) با پایگاه داده بسیار ساده می کند. در این بخش می خواهیم ویژگی به نام Entry State را به شما بشناسانیم (معرفی کنیم) که خواهید دید تا چه اندازه ساده و سودمند خواهد بود.

Entity Framework همواره از وضعیت موجودیت ها، آگاه است، زمانی که به یک Context متصل می شوند ولی در زمان نبود اتصال یا در سناریوهای N لایه، شما می توانید آشکارا به Entity Framework وضعیت یک موجودیت (مانند موجودیت کارمندان یا مشتریان) را اعلام کنید. 

پنج وضعیت گوناگون برای یک موجودیت

یک موجودیت می تواند یکی از پنچ وضعیت زیر را داشته باشد و وضعیت های زیر را داشته باشد که این وضعیت ها بر پایه مقدارهای یک Enum به نام EntryState مشخص می شوند.

  • Added: با این مقدار از Enum، موجودیت دلخواه مانند کارمندان، بدست Context شناخته و آماده پیگیری می شود ولی این وضعیت بدین معنی است که این تغییر تازه، هنوز در پایگاه داده نیست. بنابراین زمانی این مقدار را به کار می بریم که، نمونه تازه ای از موجودیت ساخته شده که باید به پایگاه داده فرستاده شود. توجه کنید بازهم تغییرها زمانی به پایگاه داده فرستاده می شوند که متد ()SaveChanges فراخوانی شود. پس از اعمال تغییرها به پایگاه داده، وضعیت موجودیت به Unchanged دگرگون می شود.
  • Unchanged: بدین معنی است که موجودیت از زمان متصل شدن به سیستم هرگز تغییری نکرده و یا اینکه، واپسین (آخرین) تغییرها به کمک متد ()SaveChanges به پایگاه داده فرستاده شده بودند.
  • Modified: موجودیت بدست Context شناخته و آماده پیگیری است و همچنین موجودیت در پایگاه داده هست ولی یکی یا همه ویژگی های آن موجودیت در برنامه تغییر پیدا کرده اند و این تغییرها باید به پایگاه داده فرستاده شوند.
  • Deleted: موجودیت بدست Context شناخته و آماده پیگیری است و همچنین موجودیت در پایگاه داده هست ولی با این وضعیت، موجودیت باید از پایگاه داده پاک شود.
  • Detached: در این وضعیت موجودیت بدست Context پیگیری نمی شود.

رفتار متد ()SaveChanges در برابر هر یک از این پنج وضعیت

وضعیت Detached که به گونه EntityState.Detached در دسترس است، وضعیتی است که در آن موجودیت به Context وصل نیست، پس بدست ()SaveChanges نیز پیگیری نمی شود.

  • Unchanged: در وضغیت EntityState.Unchanged، موجودیت به Context وصل (Attach) شده است ولی آشکار گفتیم نمی خواهیم بدست ()SaveChanges دسترسی شود. بنابرین هیچ بروز رسانی (درج، بروز رسانی و پاک شدن ) برای موجودیت با وضعیت EntityState.Unchanged انجام نمی شود.
  • Added: در وضغیت EntityState.Added، موجودیت به درون پایگاه داده درج شده و پس از پایان یافتن ()SaveChange، وضعیت آ به Unchanged دگرگون می شود. این وضعیت همان دستور INSERT در SQL است.
  • Modified: در وضغیت EntityState.Modified، متد ()SaveChanges یکی یا همه مقدار تازه ویژگی های تغییر یافته موجودیت را به پایگاه داده اعمال می کند و سپس موجودیت به وضعیت Unchanged می رود. این وضعیت همان دستور UPDATE در SQL است.
  • Deleted: در وضغیت EntityState.Modified، یک موجودیت درون پایگاه داده بدست ()SaveChanges پاک می شود و سپس موجودیت از Context قطع (یا Detached) می شود.

درج سطر تازه به درون پایگاه داده – INSERT

هر دو کد زیر، کاری یکسان را انجام می دهند ولی در دومین، بجای فراخوانی متد ()Add، نخست با دستور context.Entry(blog).State = EntityState.Added وضعیت موجودیت، که در انجام blog نام دارد را به EntityState.Added دگرگون کرده ایم و سپس متد ()SaveChanges فراخوانی شده است. در کد نخست، به گونه ای که پیش از این گفتیم، نخست متد ()Add و سپس متد ()SaveChanges فراخوانی شده است. 

بروز رسانی یک سطر درون پایگاه داده – UPDATE

گمان کنید هم اکنون یک نمونه (سطر) از موجودیت درون پایگاه داده هست و شما می خواهید آن را با مقدار تازه برای یک یا چندین یا همه ویژگی ها، بروز رسانی کنید. بناباین همانند کد زیر، نخست یک نمونه تازه از موجودیت بسازید و سپس، درون بدنه using، وضعیت آن را با دستور context.Entry(existingBlog).State = EntityState.Modified به تغییر یافته ببرید و در پایان، متد ()SaveChanges را فراخوانی کنید.