زمانی که یک پروژه چند سال فعال است یا در جریان یک بازنویسی سنگین صدها مایگریشن برای افزودن، حذف یا تغییر فیلدها ایجاد میشود، حجم بالای این فایلها سرعت بیلد، اجرای تستها و زمان پردازش مدل را کاهش میدهد. در این شرایط، هدف از Squashing این است که تاریخچه طولانی و خرد مایگریشنها به یک مایگریشن اولیه و یکپارچه (Initial/Baseline) تبدیل شود.
چالش اصلی چیست؟
اگر شما صرفاً تمام فایلهای مایگریشن قبلی را پاک کنید و یک مایگریشن جدید به نام
InitialCreate بسازید:در دیتابیس جدید: همهچیز عالی کار میکند و دیتابیس با آخرین ساختار ساخته میشود.
در دیتابیسهای عملیاتی (Production/Staging): با خطای بحرانی مواجه میشوید! چون EF Core جدول
__EFMigrationsHistory را چک میکند؛ این جدول نام تکتک مایگریشنهای قدیمی را دارد اما مایگریشن جدید شما (InitialCreate) را ندارد. در نتیجه تلاش میکند تمام جداول را از اول بسازد و با خطای Table already exists یا تخریب دیتابیس متوقف میشود.راهکار استاندارد EF Core برای تجمیع بدون شکستن دیتابیسهای موجود
برای اینکه دیتابیسهای عملیاتی متوجه شوند که نیازی به اجرای مجدد ساختار ندارند، از تکنیک هماهنگسازی تاریخچه استفاده میشود:
1️⃣ ایجاد مایگریشن نهایی و خالی (Checkpoint Migration): پیش از دست زدن به فایلهای قدیمی، ابتدا مطمئن شوید تمام محیطهای عملیاتی به آخرین وضعیت مدل آپدیت شدهاند. سپس یک مایگریشن خالی به عنوان نقطه پایان (Checkpoint) بسازید:
dotnet ef migrations add CheckpointSync
این مایگریشن هیچ تغییری در کالبد ایجاد نمیکند اما یک رکورد با Timestamp مشخص تولید میکند. نام کامل این فایل (شامل عدد تاریخ/زمان ابتدای آن، مثلاً
20260814050000_CheckpointSync) را یادداشت کنید.2️⃣ اعمال مایگریشن نهایی روی تمامی محیطهای موجود: دستور زیر را روی تمام دیتابیسهای عملیاتی، تست و توسعه اجرا کنید تا نام این مایگریشن در جدول
__EFMigrationsHistory ثبت شود:dotnet ef database update
3️⃣ حذف فیزیکی مایگریشنهای قبلی: تمام فایلهای مایگریشن موجود در پوشه
Migrations پروژه (از جمله فایل مایگریشن مرحله ۱) را حذف کنید. دقت کنید: فقط فایل Snapshot یا کدهای اصلی دیتابیس را دستکاری نکنید، صرفاً فایلهای لیست مایگریشنها را پاک کنید.4️⃣ ایجاد یک مایگریشن جامع جدید: اکنون دستور ساخت مایگریشن جدید را صادر کنید تا تمام مدل فعلی در قالب یک فایل منفرد تجمیع شود:
dotnet ef migrations add InitialBaseline
5️⃣ تطبیق نام و Timestamp مایگریشن جدید با Checkpoint: نام فایل، نام کلاس داخل فایل #C و همچنین مقدار شناسه درون فایل Snapshot تولیدشده را تغییر دهید تا دقیقاً برابر با همان نام و Timestamp مرحله اول (
20260814050000_CheckpointSync) شود.نتیجه این فرآیند چیست؟
برای پایگاهدادههای موجود (Production):
وقتی برنامه را بالا میآورید، EF Core جدول
__EFMigrationsHistory را بررسی میکند. میبیند که رکورد 20260814050000_CheckpointSync قبلاً ثبت و اجرا شده است؛ بنابراین هیچ کدی اجرا نمیکند و دیتابیس دستنخورده باقی میماند.برای پایگاهدادههای جدید (New Deployments / Local Test DBs):
دیتابیس تازه هیچ رکوردی در جدول تاریخچه ندارد؛ بنابراین همین یک مایگریشن تجمیعشده را از ابتدا اجرا میکند و تمام جداول را دقیقاً مطابق با آخرین مدل میسازد.
چه زمانی باید مایگریشنها را Squash کنیم؟
انتشار نسخه ماژور (Major Release): زمانی که نسخه جدیدی از محصول ارائه میشود و میخواهید تمام تغییرات نسخههای قبل را پاکسازی و یکدست کنید.
کاهش زمان بیلد و تست: در پروژههای بزرگ با صدها مایگریشن، سرعت ایجاد دیتابیس موقت برای تستهای یکپارچگی (Integration Tests) به شدت افزایش مییابد.
تغییرات پرشمار در فاز توسعه (قبل از Production): در شاخههای فیچر پرحجم، تجمیع مایگریشنها پیش از Merge به برنچ اصلی (Main) تاریخچهای تمیز به جا میگذارد.