O'rnatish va sozlash — NuGet, DbContext, connection string, PostgreSQL

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

Muammodan boshlaylik

EF Core nima ekanini bilamiz (49-dars). Endi uni loyihaga ulash kerak: qaysi paketlar, PostgreSQL ni qayerdan olish, connection string qanday yoziladi va qayerda saqlanadi, DbContext qanday qilib controller ga yetib keladi?


Hayotiy o'xshatma

Yangi uyga suv ulash. Quvurlar (NuGet paketlar) o'rnatiladi, shahar tarmog'iga ulanish shartnomasi (connection string) — maxfiy hujjatlar papkasida saqlanadi, kran (DbContext) esa oshxonaga o'rnatiladi va har kim undan foydalanadi. Kranni har safar quvurdan qaytadan payvandlash shart emas.


1. PostgreSQL ni ishga tushirish

Eng oson yo'l — Docker:

docker run -d --name dokon-db \
  -e POSTGRES_USER=dokon \
  -e POSTGRES_PASSWORD=dev_parol_123 \
  -e POSTGRES_DB=dokon \
  -p 5432:5432 \
  -v dokon_pgdata:/var/lib/postgresql/data \
  postgres:17

Yoki postgresql.org dan o'rnatish. Ko'rish uchun GUI: pgAdmin, DBeaver, DataGrip yoki Rider/VS Code ning ma'lumotlar bazasi plaginlari.


2. NuGet paketlar

dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install --global dotnet-ef
Paket Vazifa
Npgsql.EntityFrameworkCore.PostgreSQL PostgreSQL provayderi (EF Core ni o'zi bilan olib keladi)
Microsoft.EntityFrameworkCore.Design Migratsiyalar uchun dizayn vaqtidagi vositalar
dotnet-ef CLI: dotnet ef migrations add, database update

[!WARNING] Barcha EF Core paketlarining asosiy versiyasi bir xil bo'lsin va .NET versiyangizga mos kelsin (.NET 8 → EF Core 8.x, .NET 9 → 9.x). Aralash versiyalar — MissingMethodException kabi tushunarsiz xatolar.


3. Entity lar

// Entities/Kategoriya.cs
public class Kategoriya
{
    public int Id { get; set; }
    public string Nomi { get; set; } = "";
    public List<Mahsulot> Mahsulotlar { get; set; } = new();
}

// Entities/Mahsulot.cs
public class Mahsulot
{
    public int Id { get; set; }
    public string Nomi { get; set; } = "";
    public decimal Narx { get; set; }
    public int Qoldiq { get; set; }
    public int KategoriyaId { get; set; }
    public Kategoriya Kategoriya { get; set; } = null!;
    public DateTime YaratilganVaqt { get; set; } = DateTime.UtcNow;
}

Munosabatlar — 54-dars.


4. DbContext

// Data/DokonDbContext.cs
using Microsoft.EntityFrameworkCore;

public class DokonDbContext(DbContextOptions<DokonDbContext> options) : DbContext(options)
{
    public DbSet<Mahsulot> Mahsulotlar => Set<Mahsulot>();
    public DbSet<Kategoriya> Kategoriyalar => Set<Kategoriya>();

    protected override void OnModelCreating(ModelBuilder mb)
    {
        mb.Entity<Mahsulot>(e =>
        {
            e.Property(m => m.Nomi).HasMaxLength(200).IsRequired();
            e.Property(m => m.Narx).HasPrecision(18, 2);
            e.HasIndex(m => m.Nomi);
        });

        mb.Entity<Kategoriya>(e =>
        {
            e.Property(k => k.Nomi).HasMaxLength(100).IsRequired();
            e.HasIndex(k => k.Nomi).IsUnique();
        });
    }
}

OnModelCreating — Fluent API: ustun turlari, uzunliklar, index lar, munosabatlar. Atributlar ([MaxLength], [Required], 34-dars) bilan ham bo'ladi, lekin Fluent API kuchliroq va entity klasslarni toza saqlaydi.

Konfiguratsiyani alohida klasslarga

public class MahsulotConfig : IEntityTypeConfiguration<Mahsulot>
{
    public void Configure(EntityTypeBuilder<Mahsulot> e)
    {
        e.Property(m => m.Nomi).HasMaxLength(200).IsRequired();
        e.Property(m => m.Narx).HasPrecision(18, 2);
    }
}

protected override void OnModelCreating(ModelBuilder mb) =>
    mb.ApplyConfigurationsFromAssembly(typeof(DokonDbContext).Assembly);

Entity lar ko'p bo'lganda — har biri o'z faylida.


5. Connection string

// appsettings.json — parolsiz
{
  "ConnectionStrings": {
    "Default": "Host=localhost;Port=5432;Database=dokon;Username=dokon"
  }
}

Parol — User Secrets da (40-dars):

dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Default" "Host=localhost;Port=5432;Database=dokon;Username=dokon;Password=dev_parol_123"
Qism Ma'nosi
Host Server manzili
Port 5432 — PostgreSQL standarti
Database Baza nomi
Username, Password Kirish ma'lumotlari
Pooling=true Ulanishlar havzasi (standart yoqilgan)
SSL Mode=Require Bulutdagi bazalar uchun

6. Program.cs da ro'yxatdan o'tkazish

builder.Services.AddDbContext<DokonDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));

AddDbContext — DbContext ni Scoped qilib ro'yxatdan o'tkazadi: har bir HTTP so'rov uchun bitta (38-dars).

Development uchun qo'shimcha

builder.Services.AddDbContext<DokonDbContext>(options =>
{
    options.UseNpgsql(builder.Configuration.GetConnectionString("Default"));

    if (builder.Environment.IsDevelopment())
    {
        options.EnableSensitiveDataLogging();     // log larda parametr qiymatlari
        options.EnableDetailedErrors();
    }
});

[!WARNING] EnableSensitiveDataLogging() — log larga SQL parametr qiymatlarini (parollar xeshi, shaxsiy ma'lumotlar) yozadi. Faqat Development da.


7. Ishlatish

[ApiController]
[Route("api/[controller]")]
public class KategoriyalarController(DokonDbContext db) : ControllerBase
{
    [HttpGet]
    public async Task<List<Kategoriya>> Hammasi(CancellationToken ct) =>
        await db.Kategoriyalar.AsNoTracking().ToListAsync(ct);
}

Jadvallar hali yo'q — ularni migratsiya yaratadi (51-dars).

Ulanishni tekshirish

using var scope = app.Services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<DokonDbContext>();
Console.WriteLine(await db.Database.CanConnectAsync() ? "Bazaga ulandi" : "Ulanib bo'lmadi");

Tez-tez uchraydigan xatolar

Connection string topilmadi — ArgumentNullException: Value cannot be null (Parameter 'connectionString'); kalit nomini va User Secrets ni tekshiring.

Ulanish rad etildi:

Npgsql.NpgsqlException: Failed to connect to 127.0.0.1:5432

Baza ishlamayapti, port noto'g'ri yoki Docker container to'xtagan.

decimal uchun precision ko'rsatilmagan — ba'zi provayderlarda ogohlantirish va kutilmagan yaxlitlash; HasPrecision(18, 2).


Xulosa

O'rnatish: PostgreSQL (Docker qulay), Npgsql.EntityFrameworkCore.PostgreSQL + Microsoft.EntityFrameworkCore.Design + dotnet-ef vositasi; versiyalar mos bo'lsin. DbContext — DbSet<T> lar va OnModelCreating da Fluent API (uzunlik, precision, index); katta loyihada IEntityTypeConfiguration<T>.

Connection string — appsettings.json da parolsiz, parol — User Secrets/environment da. AddDbContext + UseNpgsql — Scoped; Development da batafsil xatolar. Jadvallar — migratsiya bilan.


Keyingi dars

51-dars: Model va Migration — Entity yaratish, Add-Migration, Update-Database