O'rnatish va sozlash — NuGet, DbContext, connection string, PostgreSQL
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 —
MissingMethodExceptionkabi 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