EF Core nima? — ORM, DbContext, DbSet, qanday ishlaydi
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.jsonda"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