Model va Migration — Entity yaratish, Add-Migration, Update-Database

~25 daq · .NET Backend · Entity Framework Core — Ma'lumotlar Bazasi

Muammodan boshlaylik

Entity lar va DbContext tayyor (50-dars), lekin bazada jadvallar yo'q. Ularni qo'lda SQL bilan yaratsangiz:

  • Mahsulot ga Tavsif maydoni qo'shildi — jadvalga ham ALTER TABLE yozish 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 __EFMigrationsHistory jadvali — 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'llash
  • Down — orqaga qaytarish
  • ModelSnapshot — 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 migratsiyadagi DropColumn/AddColumn ni qo'lda mb.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 — ModelSnapshot da 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