Model va Migration — Entity yaratish, Add-Migration, Update-Database
Muammodan boshlaylik
Entity lar va DbContext tayyor (50-dars), lekin bazada jadvallar yo'q. Ularni qo'lda SQL bilan yaratsangiz:
MahsulotgaTavsifmaydoni qo'shildi — jadvalga hamALTER TABLEyozish kerak- Hamkasbingiz o'z kompyuterida bazani qanday yangilaydi? Qaysi o'zgarishlar unda bor, qaysilari yo'q?
- Production bazasiga qaysi skriptlar qo'llangan?
Kod va baza tuzilmasi farqlanib ketadi.
Migratsiya nima?
Migratsiya — baza tuzilmasining (sxemasining) versiyalangan o'zgarishi. EF Core entity laringiz va oldingi holatni solishtirib, farqni C# kod sifatida yozadi:
Entity lar o'zgardi ──▶ dotnet ef migrations add ──▶ Migrations/20261108_TavsifQoshildi.cs
│
dotnet ef database update ▼
Baza yangilandi
- Har bir migratsiya — git da saqlanadigan fayl
- Bazada
__EFMigrationsHistoryjadvali — qaysi migratsiyalar qo'llanganini eslaydi - Har bir muhit (lokal, hamkasb, production) — bir xil tartibda yangilanadi
Hayotiy o'xshatma
Uy ta'mirining jurnali. "1-mart: oshxonaga rozetka qo'shildi", "15-mart: hammom devori surildi". Yangi usta kelsa — jurnalga qarab nima qilinganini biladi. Xuddi shu ta'mirni qo'shni xonadonda takrorlash kerak bo'lsa — jurnal bo'yicha, xuddi o'sha tartibda bajariladi.
Birinchi migratsiya
dotnet ef migrations add Boshlangich
Migrations/
├── 20261108093000_Boshlangich.cs
├── 20261108093000_Boshlangich.Designer.cs
└── DokonDbContextModelSnapshot.cs
public partial class Boshlangich : Migration
{
protected override void Up(MigrationBuilder mb)
{
mb.CreateTable(
name: "Kategoriyalar",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Nomi = table.Column<string>(maxLength: 100, nullable: false)
},
constraints: table => table.PrimaryKey("PK_Kategoriyalar", x => x.Id));
// ... Mahsulotlar, index lar
}
protected override void Down(MigrationBuilder mb)
{
mb.DropTable(name: "Mahsulotlar");
mb.DropTable(name: "Kategoriyalar");
}
}
Up— migratsiyani qo'llashDown— orqaga qaytarishModelSnapshot— modelning joriy holati (keyingi migratsiyada solishtirish uchun)
Bazaga qo'llash
dotnet ef database update
Jadvallar yaratildi.
O'zgarish qo'shish
public class Mahsulot
{
// ...
public string? Tavsif { get; set; } // yangi
public bool Faol { get; set; } = true; // yangi
}
dotnet ef migrations add MahsulotTavsifVaFaol
dotnet ef database update
protected override void Up(MigrationBuilder mb)
{
mb.AddColumn<string>(name: "Tavsif", table: "Mahsulotlar", nullable: true);
mb.AddColumn<bool>(name: "Faol", table: "Mahsulotlar", nullable: false, defaultValue: false);
}
[!WARNING] Migratsiya faylini qo'llashdan oldin o'qib chiqing. Property nomini o'zgartirsangiz (
Nomi→Nom), EF Core ko'pincha buni "eski ustunni o'chirish + yangisini qo'shish" deb tushunadi — ma'lumotlar yo'qoladi. Bunday holatda migratsiyadagiDropColumn/AddColumnni qo'ldamb.RenameColumn(...)ga almashtiring.
Asosiy buyruqlar
| Buyruq | Vazifa |
|---|---|
dotnet ef migrations add Nom |
Yangi migratsiya yaratish |
dotnet ef database update |
Barcha qo'llanmagan migratsiyalarni qo'llash |
dotnet ef database update OldingiNom |
Shu migratsiyagacha orqaga qaytish |
dotnet ef migrations remove |
Oxirgi (hali qo'llanmagan) migratsiyani o'chirish |
dotnet ef migrations list |
Ro'yxat va holati |
dotnet ef migrations script |
SQL skript yaratish |
dotnet ef database drop |
Bazani o'chirish (faqat development!) |
Visual Studio Package Manager Console da: Add-Migration Nom, Update-Database.
Production ga — SQL skript
Production da dotnet ef database update ni to'g'ridan-to'g'ri ishga tushirish o'rniga — ko'rib chiqiladigan skript:
dotnet ef migrations script --idempotent -o migrate.sql
--idempotent — skript qaysi migratsiyalar allaqachon qo'llanganini tekshiradi, shuning uchun uni qayta ishga tushirish xavfsiz. Skriptni DBA ko'rib chiqadi va CI/CD da qo'llaydi.
Ilova ishga tushganda — kichik loyihalar uchun
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<DokonDbContext>();
await db.Database.MigrateAsync();
}
[!INFO]
MigrateAsync()ni ilova ishga tushishida chaqirish — oddiy, lekin bir nechta server nusxasi bir vaqtda ishga tushsa (Kubernetes, bir nechta container) ular bir vaqtda migratsiya qilishga urinishi mumkin. Katta loyihalarda migratsiyalar — deploy jarayonining alohida qadami (skript yoki migration bundle:dotnet ef migrations bundle).
Boshlang'ich ma'lumotlar — seed
protected override void OnModelCreating(ModelBuilder mb)
{
mb.Entity<Kategoriya>().HasData(
new Kategoriya { Id = 1, Nomi = "Telefonlar" },
new Kategoriya { Id = 2, Nomi = "Noutbuklar" },
new Kategoriya { Id = 3, Nomi = "Aksessuarlar" });
}
HasData — migratsiyaga INSERT lar sifatida tushadi; Id ni aniq ko'rsatish shart. Ma'lumotnoma (kategoriyalar, rollar) uchun. Test ma'lumotlari uchun — alohida seed kodi.
Jamoaviy ishda
- Migratsiyalar git ga commit qilinadi
- Ikki dasturchi bir vaqtda migratsiya yaratsa —
ModelSnapshotda konflikt: birini o'chirib (migrations remove), boshqasini olib, qayta yarating - Qo'llangan migratsiyani tahrirlamang — u boshqa bazalarda allaqachon bajarilgan; yangi migratsiya yarating
[!TIP] Migratsiya nomlari — nima o'zgarganini aytsin:
MahsulotTavsifQoshildi,BuyurtmaHolatIndex.Migration1,Fix— bir oydan keyin hech kim tushunmaydi.
Tez-tez uchraydigan xatolar
dotnet ef topilmadi — dotnet tool install --global dotnet-ef.
Unable to create a 'DbContext' — dizayn vaqtida DbContext yaratilmadi: Microsoft.EntityFrameworkCore.Design paketi yo'q yoki Program.cs da connection string topilmadi.
Nom o'zgartirish — ma'lumot yo'qolishi — migratsiyani ko'rib chiqing, RenameColumn.
Qo'llangan migratsiyani o'chirish/tahrirlash — bazalar orasida nomuvofiqlik.
Xulosa
Migratsiya — baza sxemasining versiyalangan o'zgarishi, C# kod sifatida, git da saqlanadi; qo'llanganlari __EFMigrationsHistory da. dotnet ef migrations add Nom → faylni ko'rib chiqing → dotnet ef database update. Up — qo'llash, Down — orqaga.
Nom o'zgartirish — RenameColumn ga tuzating, aks holda ma'lumot yo'qoladi. Production — migrations script --idempotent yoki bundle; kichik loyihada MigrateAsync(). Seed — HasData. Qo'llangan migratsiyani tahrirlamang; nomlar tushunarli bo'lsin.
Keyingi dars
52-dars: CRUD — Add, Find, Update, Remove, SaveChangesAsync