Entity Framework Core, Microsoft tarafından geliştirilen ve modern .NET uygulamalarında veritabanı işlemlerini kolaylaştırmak için kullanılan popüler bir nesne ilişkisel eşleme (ORM) aracıdır. Bu makalede, Entity Framework Core’un temel yapıları, performans optimizasyonları, migration işlemleri ve daha birçok derinlemesine konu ele alınacaktır.

Entity Framework Core Nedir?

Entity Framework Core (EF Core), .NET platformu için hafif, genişletilebilir ve platform bağımsız bir ORM (Object-Relational Mapping) aracıdır. EF Core, geliştiricilerin veritabanı işlemlerini SQL sorguları yazmadan nesne yönelimli programlama (OOP) yaklaşımıyla gerçekleştirmesine olanak tanır. Bu sayede veritabanı ile uygulama katmanı arasında bir köprü görevi görür.

EF Core, Entity Framework’ün yeniden tasarlanmış halidir. .NET Core ile uyumlu olarak geliştirilmiş olup, .NET 5, 6 ve daha yeni sürümlerinde de desteklenmektedir. Ayrıca açık kaynaklıdır ve GitHub üzerinde aktif olarak geliştirilmektedir.

Temel Bileşenler ve Yapılar

EF Core’u derinlemesine anlamak için öncelikle temel yapı taşlarını bilmek gerekir. Bu yapılar arasında DbContext, DbSet, Entity ve Configuration sınıfları yer alır.

  • DbContext: EF Core uygulamasının kalbidir. Veritabanı bağlantısını yönetir, sorguları çalıştırır ve değişiklikleri veritabanına kaydeder.
  • DbSet: Entity türlerinin koleksiyonunu temsil eder. Örneğin, bir “Products” tablosu için DbSet tanımlanır.
  • Entity: Veritabanındaki bir tabloya karşılık gelen sınıftır. Özellikleri (properties) tablo sütunlarıyla eşleşir.
  • Configuration: Fluent API kullanılarak model yapılandırması yapılır. Öznitelik tabanlı yapılandırmalara alternatif olarak kullanılır.

Veri Modellenmesi ve İlişkiler

EF Core, veritabanı nesnelerinin modellenmesini destekler. Birebir, bire çok ve çoktan çoğa ilişkiler kurulabilir.

Örneğin, bir kullanıcı birden fazla siparişe sahip olabilir. Bu durumda User ile Order arasında bire çok bir ilişki tanımlanabilir:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

Bu ilişkiler, Fluent API ile de yapılandırılabilir. Örneğin:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>()
        .HasOne(o => o.User)
        .WithMany(u => u.Orders)
        .HasForeignKey(o => o.UserId);
}

Migration Kullanımı ve Veritabanı Yönetimi

EF Core, migration adı verilen yapılarla veritabanı şemasını kod ile senkronize tutar. Migrationlar, veritabanı şemasında yapılan değişikliklerin izlenmesini ve uygulanmasını sağlar.

Yeni bir migration oluşturmak için aşağıdaki komut kullanılır:

Add-Migration InitialCreate

Bu komut, modelde yapılan değişiklikleri yansıtan bir migration sınıfı oluşturur. Ardından veritabanına uygulamak için:

Update-Database

Migrationlar sayesinde veritabanı şeması versiyonlanabilir ve takım çalışması sırasında senkronizasyon sağlanabilir. Ayrıca, üretim ortamında da migration script’leri oluşturulup uygulanabilir.

Veri Sorgulama Yöntemleri

EF Core ile veri sorgulama LINQ (Language Integrated Query) sorguları ile yapılır. LINQ sayesinde veritabanı sorguları C# kodu gibi yazılabilir.

Basit bir sorgu örneği:

var users = context.Users.Where(u => u.Name.Contains("Ahmet")).ToList();

EF Core aynı zamanda raw SQL sorgularını da destekler. Özellikle karmaşık sorgular veya performans gerektiren işlemler için bu yöntem kullanılabilir:

var users = context.Users.FromSqlRaw("SELECT * FROM Users WHERE Name LIKE '%Ahmet%'").ToList();

İzleme (tracking) ve izleme dışı (no-tracking) sorgular da önemli bir konudur. Özellikle sadece okuma yapılacak sorgularda AsNoTracking() metodu performansı artırabilir:

var users = context.Users.AsNoTracking().ToList();

Performans Optimizasyonu

EF Core performans açısından dikkat edilmesi gereken birçok noktaya sahiptir. Sorgular sırasında gereksiz veri yüklemeleri, N+1 problemi, lazy loading kullanımı gibi etkenler performansı doğrudan etkiler.

  • Eager Loading: Include() yöntemi ile ilişkili verilerin anında yüklenmesi sağlanabilir.
  • Explicit Loading: Gerektiğinde ilişkili verilerin manuel olarak yüklenmesidir.
  • Select Projection: Sadece gerekli alanların seçilmesi, veri trafiğini azaltır.

Örnek olarak, kullanıcılar ve ilişkili siparişler için eager loading kullanımı:

var usersWithOrders = context.Users.Include(u => u.Orders).ToList();

Change Tracking ve EntityState

EF Core, nesneler üzerinde yapılan değişiklikleri otomatik olarak izler. Bu işlem, ChangeTracker bileşeni tarafından yapılır. Nesnelerin durumu EntityState ile izlenir:

  • Unchanged
  • Added
  • Modified
  • Deleted
  • Detached

Bu durumlar, SaveChanges() metodu çağrıldığında hangi işlemlerin veritabanına yansıtılacağını belirler.

Transaction ve Concurrency Kontrolü

EF Core, veritabanı işlemlerinde transaction yönetimini de destekler. Varsayılan olarak her SaveChanges çağrısı bir transaction içinde yürütülür. Ancak ihtiyaç durumunda manuel transaction da başlatılabilir:

using var transaction = context.Database.BeginTransaction();
try
{
    context.Users.Add(new User { Name = "Ali" });
    context.SaveChanges();

    context.Orders.Add(new Order { UserId = 1 });
    context.SaveChanges();

    transaction.Commit();
}
catch
{
    transaction.Rollback();
}

Ayrıca EF Core, optimistik concurrency kontrolünü destekler. Bu yöntem sayesinde veri çakışmaları önlenir. Örneğin ConcurrencyCheck veya Timestamp attribute’leri kullanılabilir.

Advanced Mapping ve Inheritance

EF Core, tablo başına hiyerarşi (TPH), tablo başına tip (TPT) gibi kalıtım yapılarını destekler. TPH yaklaşımında tüm türetilmiş sınıflar tek bir tabloda saklanır ve bir ayırt edici sütun ile ayrılır:

modelBuilder.Entity<BaseEntity>()
    .HasDiscriminator<string>("Type")
    .HasValue<User>("User")
    .HasValue<Admin>("Admin");

Asenkron Programlama ve EF Core

EF Core, asenkron işlemleri destekler. Özellikle web uygulamalarında UI thread’in bloke olmaması için bu yöntemler çok önemlidir. ToListAsync(), SaveChangesAsync() gibi async metotlar kullanılabilir:

var users = await context.Users.Where(u => u.IsActive).ToListAsync();

Sonuç

Entity Framework Core, modern .NET uygulamalarında veritabanı işlemlerini kolaylaştıran güçlü bir ORM aracıdır. Performans, veri modellenmesi ve sorgulama gibi konularda derinlemesine bilgi sahibi olmak, uygulamaların güvenli ve verimli çalışmasını sağlar. EF Core’un sunduğu esneklik ve yetenekler sayesinde, karmaşık veritabanı işlemlerini bile nesne yönelimli bir yaklaşımla yönetmek mümkündür.

Bir önceki yazımız olan Print Screen Engelleme başlıklı makalemizde Engelleme, İşletim Sistemi ve key logger hakkında bilgiler verilmektedir.