Mert Özen Her Satırda Daha İleri
Backend .NET Core Web API — #09

Entity Framework Core'a giriş: DbContext ve ilk migration

Mert Özen 2 Ağu 2026 13 dk 77 görüntülenme
Entity Framework Core'a giriş: DbContext ve ilk migration

Verimizi gerçek bir veritabanında saklamaya başlıyoruz. EF Core nedir, DbContext neyi temsil eder, DbSet ile tablolar nasıl tanımlanır ve ilk migration ile veritabanı nasıl oluşturulur, adım adım.

Şimdiye kadar hep hile yaptık. Kullanıcılarımız bellekte, sabit bir dizinin içinde yaşıyordu; uygulamayı her kapattığımızda hepsi uçup gidiyordu. Öğrenmek için bu gayet iyiydi ama gerçek bir uygulama böyle çalışmaz. Verinin kalıcı olması, yani bir veritabanında saklanması gerekir. Bugün Entity Framework Core ile tanışıyor ve verimizi ilk kez gerçek bir veritabanına yazıyoruz.

Entity Framework Core Nedir?

Entity Framework Core, kısaca EF Core, .NET dünyasının en yaygın ORM'idir. ORM, "Object-Relational Mapping" yani nesne-ilişkisel eşleme demek. Kulağa karmaşık geliyor ama işi aslında çok net: senin C# nesnelerin ile veritabanındaki tablolar arasında bir köprü kurar.

Bu köprü olmadan, veritabanıyla konuşmak için elle SQL sorguları yazman gerekirdi. Bir kullanıcı çekmek için SELECT, eklemek için INSERT cümleleri... EF Core bu yükü senden alır. Sen users.Add(user) gibi tanıdık C# kodu yazarsın, EF Core ise arka planda bunu uygun SQL'e çevirip veritabanına gönderir. Yani sen nesnelerle düşünmeye devam edersin, veritabanı diline çeviriyi o yapar. İki farklı dil konuşan iki tarafın arasındaki tercüman gibi.

Önce Paketleri Ekleyelim

EF Core, .NET'in içinde hazır gelmez; projene ayrıca eklemen gerekir. Bu seride örnekleri sade tutmak için SQLite kullanacağız; dosya tabanlı, kurulum gerektirmeyen, öğrenmek için ideal bir veritabanı. Projenin klasöründe terminali aç ve şu iki paketi ekle:

dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design

İlk paket SQLite ile çalışmak için gereken sağlayıcı; ikincisi ise birazdan kullanacağımız migration komutları için gerekli. Kurulum bittiğinde EF Core'u kullanmaya hazırsın.

DbContext: Veritabanına Açılan Kapı

EF Core'un kalbi DbContext sınıfıdır. Onu, uygulaman ile veritabanı arasındaki tek kapı gibi düşün. Veritabanıyla ilgili her işlem bu kapıdan geçer: veri okumak, eklemek, güncellemek, silmek. Kendi context sınıfımızı, EF Core'un DbContext sınıfından türeterek oluşturuyoruz:

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions options)
        : base(options)
    {
    }

    public DbSet Users { get; set; }
}

Bu kısacık sınıfta iki önemli şey var. Yapıcı metot (constructor) DbContextOptions alıyor; bu, hangi veritabanına nasıl bağlanacağımızın ayarlarını taşıyor ve birazdan bu ayarları Program.cs'te vereceğiz. Asıl dikkat çeken ise DbSet<User> Users satırı.

DbSet: Bir Tablonun Temsilcisi

DbSet<User>, veritabanındaki bir tabloyu temsil eder. Bu satır EF Core'a şunu söylüyor: "Veritabanında User nesnelerini tutan bir Users tablosu olacak." Her DbSet, bir tabloya karşılık gelir. İleride ürünler eklersen DbSet<Product> Products, siparişler eklersen DbSet<Order> Orders yazarsın.

Bunu bir Excel dosyası gibi düşünebilirsin: DbContext tüm dosya, her DbSet ise o dosyadaki ayrı bir sayfa. Kodun içinde context.Users yazdığında, aslında o tablonun tamamına erişiyorsun demektir; oradan sorgu yapabilir, yeni satır ekleyebilir, var olanı güncelleyebilirsin.

DbContext'i Program.cs'e Tanıtmak

Context sınıfını yazdık ama EF Core'un bunu tanıması ve hangi veritabanına bağlanacağını bilmesi gerekiyor. Bunu, ikinci yazıdan tanıdığın servis kayıt aşamasında, yani builder.Build()'dan önce yapıyoruz:

builder.Services.AddDbContext(options =>
    options.UseSqlite("Data Source=app.db"));

Bu satır iki iş yapıyor. AddDbContext ile context'imizi sisteme kaydediyor, UseSqlite ile de hangi veritabanını kullanacağımızı söylüyoruz. "Data Source=app.db" ise bağlantı dizesi (connection string); burada uygulamanın çalıştığı klasörde app.db adında bir SQLite dosyası kullanılacağını belirtiyoruz. Gerçek projelerde bu bağlantı dizesini doğrudan koda yazmak yerine appsettings dosyasında tutarız; o konuya configuration yazısında değineceğiz.

Migration: Nedir, Neden Gerekli?

Sınıflarımız hazır ama ortada henüz bir veritabanı yok. İşte migration tam burada devreye giriyor. Migration, senin C# sınıflarındaki yapıyı alıp veritabanına uygulanacak somut adımlara çeviren bir plandır. "Şu tabloyu oluştur, şu sütunları ekle" gibi talimatları senin yerine üretir.

Migration'ı, veritabanının versiyon kontrolü gibi düşün. Kod tarafında bir değişiklik yaptığında (mesela entity'ne yeni bir alan eklediğinde) yeni bir migration oluşturursun ve EF Core bu değişikliği veritabanına nasıl yansıtacağını bilir. Böylece veritabanının yapısı hep kodunla senkron kalır ve bu geçmişi adım adım takip edebilirsin.

İlk Migration'ı Oluşturmak ve Uygulamak

Migration'ları yönetmek için EF Core'un komut satırı aracına ihtiyacımız var. Bir kez kurman yeterli:

dotnet tool install --global dotnet-ef

Şimdi ilk migration'ımızı oluşturuyoruz. Buna anlamlı bir isim veriyoruz; ilk kurulum olduğu için "InitialCreate" uygun bir isim:

dotnet ef migrations add InitialCreate

Bu komut, projende Migrations adında bir klasör oluşturur ve içine, Users tablosunu nasıl oluşturacağını anlatan kod dosyaları koyar. Ama dikkat: bu adım henüz veritabanına dokunmadı, sadece planı hazırladı. Planı gerçekten uygulamak, yani veritabanını oluşturmak için şu komutu çalıştırıyoruz:

dotnet ef database update

Bu komut çalıştığında, projenin klasöründe app.db adında bir SQLite dosyası belirir ve içinde senin Users tablon oluşur. İşte artık gerçek, kalıcı bir veritabanın var. Uygulamayı kapatıp açsan da veriler yerinde duracak.

Küçük Bir Deneme

Yukarıdaki adımları kendi projende baştan sona uygula: paketleri ekle, AppDbContext'i yaz, Program.cs'te kaydet, sonra migration oluşturup veritabanını güncelle. Klasöründe beliren app.db dosyasını gör. İstersen ücretsiz bir SQLite görüntüleyici ile bu dosyayı açıp Users tablosunun sütunlarını incele; entity'ndeki her özelliğin bir sütuna dönüştüğünü kendi gözünle görmek, EF Core'un ne yaptığını çok net oturtur. Henüz tabloda veri yok, ama yapı hazır.

Bir sonraki yazıda bu veritabanını gerçekten kullanmaya başlıyoruz: controller'ımızdan DbContext üzerinden veri okuyup yazacak, servis katmanının ne işe yaradığını ve "repository pattern gerçekten gerekli mi?" sorusunu tartışacağız. Bugün kurduğun bu temel, kalan her şeyin üzerine oturacağı zemin.