EF Core nima? — ORM, DbContext, DbSet, qanday ishlaydi

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

Muammodan boshlaylik

Ma'lumotlar bazasi bilan "xom" ADO.NET orqali ishlash:

using var conn = new NpgsqlConnection(connStr);
await conn.OpenAsync();
using var cmd = new NpgsqlCommand("SELECT id, nomi, narx, qoldiq FROM mahsulotlar WHERE narx < @narx", conn);
cmd.Parameters.AddWithValue("narx", 100000m);
using var reader = await cmd.ExecuteReaderAsync();

var royxat = new List<Mahsulot>();
while (await reader.ReadAsync())
{
    royxat.Add(new Mahsulot
    {
        Id = reader.GetInt32(0),
        Nomi = reader.GetString(1),
        Narx = reader.GetDecimal(2),
        Qoldiq = reader.GetInt32(3),
    });
}

Bitta oddiy so'rov uchun 15 qator. Ustun nomi o'zgarsa — SQL satri ichidagi xato faqat ishlash paytida. Har bir jadval uchun — xuddi shu kod. Jadval yaratish va o'zgartirish — qo'lda SQL skriptlar.


ORM nima?

ORM (Object-Relational Mapper) — ma'lumotlar bazasi jadvallarini C# klasslari bilan bog'laydigan vosita. Siz C# ob'ektlar va LINQ bilan ishlaysiz, ORM uni SQL ga o'giradi.

var royxat = await db.Mahsulotlar
    .Where(m => m.Narx < 100000m)
    .ToListAsync();

EF Core avtomatik SQL yaratadi:

SELECT m."Id", m."Nomi", m."Narx", m."Qoldiq"
FROM "Mahsulotlar" AS m
WHERE m."Narx" < 100000.0

Entity Framework Core — Microsoft ning .NET uchun rasmiy ORM i.

Jadval dunyosi C# dunyosi
Jadval Klass (entity)
Qator Ob'ekt
Ustun Property
Foreign key Navigation property (54-dars)
SQL so'rov LINQ

Hayotiy o'xshatma

Tarjimon. Siz o'z tilingizda (C#, LINQ) gapirasiz: "narxi 100 mingdan arzon mahsulotlarni ber". Tarjimon buni bazaning tiliga (SQL) to'g'ri o'giradi, javobni qaytarib tarjima qiladi va C# ob'ektlari ko'rinishida beradi. Siz baza tilini mukammal bilishingiz shart emas — lekin tarjimon nima deyayotganini tushunish foydali.


Asosiy tushunchalar

Entity

public class Mahsulot
{
    public int Id { get; set; }                 // avtomatik primary key
    public string Nomi { get; set; } = "";
    public decimal Narx { get; set; }
    public int Qoldiq { get; set; }
    public DateTime YaratilganVaqt { get; set; } = DateTime.UtcNow;
}

Oddiy C# klass — bazadagi jadval qatorini ifodalaydi. Id (yoki MahsulotId) — konvensiya bo'yicha primary key.

DbContext

using Microsoft.EntityFrameworkCore;

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

DbContext — baza bilan ishlash sessiyasi:

  • Ulanishni boshqaradi
  • So'rovlarni SQL ga o'giradi
  • Yuklangan ob'ektlarning o'zgarishlarini kuzatadi (change tracking)
  • SaveChangesAsync() da barcha o'zgarishlarni bitta tranzaksiyada saqlaydi

DbSet

DbSet<Mahsulot> — bitta jadval: undan so'rov qilinadi va unga qo'shiladi.


Qanday ishlaydi — change tracking

var m = await db.Mahsulotlar.FindAsync(5);   // SELECT ... WHERE Id = 5
m!.Narx = 135000m;                           // faqat xotirada
m.Qoldiq -= 1;

db.Mahsulotlar.Add(new Mahsulot { Nomi = "Kosa", Narx = 30000m });

await db.SaveChangesAsync();
// BEGIN TRANSACTION
// UPDATE Mahsulotlar SET Narx = 135000, Qoldiq = 9 WHERE Id = 5
// INSERT INTO Mahsulotlar (Nomi, Narx, ...) VALUES ('Kosa', 30000, ...)
// COMMIT

DbContext yuklangan ob'ektlarning asl holatini eslab qoladi. SaveChangesAsync() da u nimalar o'zgarganini aniqlaydi va faqat kerakli UPDATE/INSERT/DELETE larni yuboradi — bitta tranzaksiyada: yo hammasi saqlanadi, yo hech biri.


Qo'llab-quvvatlanadigan bazalar

Baza NuGet provayder
PostgreSQL Npgsql.EntityFrameworkCore.PostgreSQL
SQL Server Microsoft.EntityFrameworkCore.SqlServer
SQLite Microsoft.EntityFrameworkCore.Sqlite
MySQL Pomelo.EntityFrameworkCore.MySql
In-memory (faqat test) Microsoft.EntityFrameworkCore.InMemory

Kod deyarli bir xil — provayderni almashtirish mumkin. Kursda — PostgreSQL (50-dars).


Ishlash usullari

Usul Ma'nosi
Code First Avval C# klasslar, ulardan migratsiyalar orqali jadvallar (51-dars) — yangi loyihalar uchun asosiy
Database First Mavjud bazadan klasslarni generatsiya qilish: dotnet ef dbcontext scaffold

EF Core afzalliklari va narxi

✅ Afzallik ⚠️ E'tibor talab qiladi
LINQ — turlangan, kompilyator tekshiradi Generatsiya qilingan SQL ni tushunish kerak
Takrorlanuvchi kod yo'q N+1 so'rov muammosi (53-dars)
Migratsiyalar — baza tuzilmasi versiyalangan Juda murakkab hisobotlar — xom SQL yaxshiroq
SQL injection dan himoya (parametrlar) Change tracking — xotira va tezlik narxi
Bazani almashtirish oson

[!TIP] Development da EF Core yuborayotgan SQL ni ko'rib turing: appsettings.Development.json da "Microsoft.EntityFrameworkCore.Database.Command": "Information" log darajasi. "Bu LINQ qanday SQL ga aylandi?" degan savolga javob — performance muammolarining ko'pini erta topadi.

[!INFO] Juda yuqori tezlik va to'liq SQL nazorati kerak bo'lgan joylarda Dapper (yengil "micro-ORM") ham ishlatiladi: SQL ni o'zingiz yozasiz, u faqat natijani ob'ektlarga aylantiradi. Ko'p loyihalar ikkalasini birga ishlatadi: oddiy CRUD — EF Core, og'ir hisobotlar — Dapper.


Tez-tez uchraydigan xatolar

DbContext ni Singleton qilish — u thread-safe emas; Scoped (38-dars, AddDbContext buni o'zi qiladi).

SaveChanges ni unutish — o'zgarishlar faqat xotirada qoladi.

SQL ni bilmasdan ishlash — sekin so'rovlarning sababi ko'rinmaydi.


Xulosa

ORM — jadvallarni klasslarga bog'laydi: siz LINQ va ob'ektlar bilan ishlaysiz, u SQL ga o'giradi. EF Core — .NET ning rasmiy ORM i.

Entity — jadval qatori (klass), DbSet<T> — jadval, DbContext — sessiya: ulanish, so'rovlar, change tracking. SaveChangesAsync() — barcha o'zgarishlarni bitta tranzaksiyada saqlaydi. Provayderlar: PostgreSQL, SQL Server, SQLite, MySQL. Code First — klasslardan migratsiya orqali jadvallar. Generatsiya qilingan SQL ni kuzating.


Keyingi dars

50-dars: O'rnatish va sozlash — NuGet, DbContext, connection string, PostgreSQL