EF Core veritabanı sağlayıcısı (database provider), Entity Framework Core'un belirli bir veritabanıyla konuşmasını sağlayan eklenti kütüphanesidir ve genellikle bir NuGet paketi olarak gelir. SQL Server için Microsoft.EntityFrameworkCore.SqlServer, SQLite için Microsoft.EntityFrameworkCore.Sqlite paketini ekler, DbContext yapılandırmasında UseSqlServer veya UseSqlite çağırırsınız. PostgreSQL için Npgsql, MySQL ve MariaDB için Pomelo gibi sağlayıcılar ise Microsoft dışındaki ekipler tarafından geliştirilir.

Bu yazıda resmî belgelerdeki sağlayıcı tablosunu, sağlayıcı seçerken dikkat edilecek sürüm kurallarını, sağlayıcının nasıl eklendiğini ve Microsoft'un bakımını yaptığı dört sağlayıcının (SQL Server, SQLite, InMemory, Azure Cosmos DB) önemli farklarını, özellikle SQLite'ın migration sınırlamalarını anlatıyoruz. Veritabanlarının kendisini anlatan yazılarımız ayrı: SQL Server nedir, SQLite nedir, PostgreSQL nedir, MySQL nedir ve MariaDB rehberi. Hangi veritabanını seçeceğinize henüz karar vermediyseniz MySQL ve PostgreSQL karşılaştırmasına bakabilirsiniz. Serinin tamamı için EF Core öğrenme rehberi.

Sağlayıcı ne yapar?

Belgeler EF Core'daki kavramları üç katmanda anlatır. Bazı kavramlar çoğu veritabanında ortaktır ve EF Core'un ana bileşenlerindedir: sorguları LINQ ile ifade etmek, transaction'lar ve veritabanından yüklenen nesnelerdeki değişiklikleri izlemek gibi. Bazı kavramlar bir sağlayıcı sınıfına özgüdür: ilişkisel veritabanları için sağlayıcılar ortak Microsoft.EntityFrameworkCore.Relational kütüphanesinin üzerine kurulur; tablo ve kolon eşleme, yabancı anahtar kısıtları gibi API'ler buradan gelir. Bazı kavramlar ise tek bir sağlayıcıya özgüdür; belgelerin örneği SQL Server'a özgü bellek için optimize edilmiş tablolardır. Sağlayıcı ayrıca LINQ sorgularınızı o veritabanının SQL lehçesine çevirir ve migration işlemlerinden SQL üretir; bu yüzden aynı model farklı sağlayıcılarda farklı SQL ve farklı yeteneklerle sonuçlanır.

Sağlayıcı tablosu

Sağlayıcı tablosu: Microsoft.EntityFrameworkCore.SqlServer, Microsoft.EntityFrameworkCore.Sqlite, Microsoft.EntityFrameworkCore.InMemory, Microsoft.EntityFrameworkCore.Cosmos

Belgelerdeki güncel sağlayıcı listesinden bir seçki aşağıdadır. “EF Core” kolonu, tabloda o sağlayıcı için belirtilen EF Core ana sürümlerini gösterir; belgeler bu bilginin sağlayıcının kendi belgelerinden doğrulanmasını ister.

NuGet paketiVeritabanıBakımı yapanTablodaki EF Core sürümleri
Microsoft.EntityFrameworkCore.SqlServerAzure SQL, SQL Server, Azure Synapse AnalyticsEF Core Project (Microsoft)8, 9, 10
Microsoft.EntityFrameworkCore.SqliteSQLite 3.46.1 ve sonrasıEF Core Project (Microsoft)8, 9, 10
Microsoft.EntityFrameworkCore.InMemoryEF Core bellek içi veritabanıEF Core Project (Microsoft)8, 9, 10
Microsoft.EntityFrameworkCore.CosmosAzure Cosmos DB SQL APIEF Core Project (Microsoft)8, 9, 10
Npgsql.EntityFrameworkCore.PostgreSQLPostgreSQLNpgsql Development Team8, 9
Pomelo.EntityFrameworkCore.MySqlMySQL, MariaDBPomelo Foundation Project8, 9
MySql.EntityFrameworkCoreMySQLMySQL project (Oracle)8, 9
Oracle.EntityFrameworkCoreOracle DB 19c ve sonrasıOracle8, 9, 10
MongoDB.EntityFrameworkCoreMongoDBMongoDB8, 9, 10
FirebirdSql.EntityFrameworkCore.FirebirdFirebird 3.0 ve sonrasıJiří Činčura10

Tablonun tamamında Devart'ın ücretli sağlayıcıları, IBM Db2, Google Cloud Spanner, DuckDB, YDB gibi başka sağlayıcılar da bulunur. Tabloyu okurken dikkat edin: snapshot tarihindeki belgelerde Npgsql ve Pomelo satırlarında EF Core sütunu “8, 9” olarak görünüyor. Bu, EF Core 10 ile kullanıp kullanamayacağınızı söylemek için yeterli bir bilgi değildir; sürüm uyumluluğunu her zaman sağlayıcının kendi belgelerinden ve NuGet sayfasından doğrulayın. Bu yazıda üçüncü taraf sağlayıcıların kendi API ayrıntılarına girmiyoruz, çünkü bunlar EF Core belgelerinin değil o projelerin belgelerinin konusudur.

Sağlayıcı eklemek ve yapılandırmak

Çoğu sağlayıcı bir NuGet paketi olarak dağıtılır ve projeye paket olarak eklenir. Paketi ekledikten sonra sağlayıcıyı DbContext içinde ya OnConfiguring metodunda ya da bağımlılık enjeksiyonu kullanıyorsanız AddDbContext çağrısında yapılandırırsınız. Paketlerin tam listesi ve Design/Tools paketleri EF Core kurulumu yazısında, AddDbContext ve OnConfiguring farkı DbContext yapılandırma yazısında anlatılıyor.

bash
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
csharp
public class MyContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("<CONNECTION STRING>");
    }
}
csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MyContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MyContext")));

SQL Server sağlayıcısı

SQL Server sağlayıcısı: Bağlantı dayanıklılığı, Application Name, Trigger ve OUTPUT, Microsoft Entra ID bağımlılığı

SQL Server sağlayıcısı EF Core projesinin parçasıdır ve Azure SQL ile Azure Synapse Analytics'i de kapsar. Yerinde kurulu SQL Server için UseSqlServer, Azure SQL için UseAzureSql, Azure Synapse için UseAzureSynapse kullanılır; son ikisi EF Core 9 ile geldi. Sağlayıcı altta ADO.NET sürücüsü olarak Microsoft.Data.SqlClient kullanır; eski System.Data.SqlClient değil. Projeniz SqlClient'a doğrudan bağımlıysa Microsoft.Data.SqlClient paketine referans verdiğinden emin olun. SqlClient paketi EF Core sağlayıcısından daha sık yayımlandığı için yeni özellik ve düzeltmeler için ona doğrudan referans ekleyebilirsiniz.

Uyumluluk düzeyi (compatibility level)

EF'i veritabanınızın uyumluluk düzeyiyle yapılandırabilirsiniz; daha yüksek düzeyler daha yeni özelliklere izin verir ve EF de bunlardan yararlanan SQL üretir. Açıkça yapılandırmazsanız makul bir varsayılan seçilir, ama bu varsayılan en yeni özellikleri kullanmayabilir; bu yüzden belgeler düzeyi açıkça belirtmenizi önerir. Bu ayar yalnızca EF'in kendi davranışını (örneğin ürettiği SQL'i) etkiler, veritabanınızdaki uyumluluk düzeyini değiştirmez; yeni bir SQL Server sürümünde barındırılan bir veritabanı daha düşük bir düzeyle yapılandırılmış olabilir.

csharp
optionsBuilder.UseSqlServer("<CONNECTION STRING>", o => o.UseCompatibilityLevel(170));

Bu ayarın EF Core 10'da somut bir sonucu var: UseAzureSql kullanıyorsanız veya uyumluluk düzeyini 170 ya da üstüne ayarladıysanız, JSON'a eşlenen primitive koleksiyonlar ve owned tipler artık nvarchar(max) yerine SQL Server'ın yeni json veri tipine eşleniyor. Mevcut bir uygulamada bu, ilk migration'da var olan JSON kolonlarını json tipine çeviren bir değişiklik üretir. Belgelere göre bu değişiklik sorunsuz uygulanmalı ama veritabanınızda küçük olmayan bir değişikliktir; istemiyorsanız kolon tipini elle nvarchar(max) yapabilir veya 170'ten düşük bir uyumluluk düzeyi kullanabilirsiniz. Ayrıntı: EF Core 10 yenilikleri.

Diğer SQL Server notları

  • Bağlantı dayanıklılığı: UseAzureSql ve UseAzureSynapse ile otomatik yeniden deneme uygun ayarlarla kendiliğinden kurulur; UseSqlServer ile EnableRetryOnFailure yapılandırmanız gerekir. Ayrıntı: connection resiliency.
  • Application Name: EF Core 10'dan itibaren bağlantı dizesinde Application Name yoksa EF, EF ve SqlClient sürümleri hakkında anonim bilgi içeren bir değer ekliyor. Aynı veritabanına EF ve başka bir teknolojiyle (Dapper, ADO.NET) bağlanıyorsanız farklı bağlantı havuzları oluşabilir; TransactionScope içinde bu, dağıtık transaction'a yükselmeye yol açabilir. Çözüm bağlantı dizesinde kendi Application Name değerinizi tanımlamaktır.
  • Trigger ve OUTPUT: EF Core kaydederken T-SQL OUTPUT ifadesini kullanır; bu ifade trigger içeren tablolarla kullanılamaz. Böyle bir tabloda ToTable(tb => tb.UseSqlOutputClause(false)) ile eski ve daha az verimli tekniğe geçersiniz.
  • Microsoft Entra ID bağımlılığı: EF Core 10 kırıcı değişiklik notlarına göre Microsoft.Data.SqlClient 6.1.6, Entra ID kimlik doğrulaması için bir broker bağımlılığı ekliyor ve yayımlanan uygulamanın boyutunu belirgin şekilde artırabiliyor; Entra ID kullanmıyorsanız notlardaki önerilere bakın.

SQLite sağlayıcısı

SQLite sağlayıcısı da EF Core projesinin parçasıdır ve SQLite 3.46.1 ve sonrasını destekler. Belgeler bu sağlayıcının bir dizi önemli sınırlamasını, özellikle migration tarafındakileri, ayrı bir sayfada toplar. Bunların çoğu EF'e özgü değildir, SQLite motorunun kendi sınırlamalarından gelir. SQLite ile ilk uygulamanızı yazmak isterseniz SQLite ile ilk EF Core uygulaması yazısından başlayabilirsiniz.

Modelleme ve sorgu sınırlamaları

İlişkisel sağlayıcıların ortak kütüphanesindeki bazı kavramlar SQLite'ta desteklenmez: şemalar, sequence'ler ve veritabanı tarafından üretilen eşzamanlılık belirteçleri. Sorgu tarafında SQLite DateTimeOffset, TimeSpan ve ulong tiplerini yerel olarak desteklemez. EF Core bu tiplerdeki değerleri okuyup yazabilir ve eşitlik sorgusu yapabilir; ama karşılaştırma ve sıralama gibi işlemler SQL'e çevrilmez ve istemci tarafında değerlendirilmesi gerekir. Belgeler DateTimeOffset yerine DateTime kullanmayı, birden çok saat dilimiyle çalışıyorsanız değerleri kaydetmeden önce UTC'ye çevirmeyi önerir. İstemci tarafı değerlendirme konusu client evaluation yazısında anlatılıyor.

decimal da SQLite'ta yerel olarak yoktur; ancak EF Core karşılaştırma, sıralama, aritmetik ve toplama işlemlerini bağlantıya kaydettiği fonksiyonlar ve bir collation ile (ef_compare, EF_DECIMAL gibi) çevirir. decimal hassasiyetine ihtiyacınız yoksa double kullanabilir, sınıflarınızda decimal tutmaya devam etmek için bir değer dönüştürücü ekleyebilirsiniz:

csharp
modelBuilder.Entity<MyEntity>()
    .Property(e => e.DecimalProperty)
    .HasConversion<double>();

Migration sınırlamaları ve rebuild

SQLite, diğer ilişkisel veritabanlarının çoğunun desteklediği bazı şema işlemlerini desteklemez. EF Core bu işlemlerin bir kısmını tabloyu yeniden kurarak (rebuild: yeni tablo oluştur, veriyi kopyala, eskiyi sil, yeniyi yeniden adlandır) gerçekleştirir. Rebuild yalnızca EF Core modelinin parçası olan nesneler için mümkündür; örneğin migration içinde elle oluşturulmuş bir nesne söz konusuysa yine NotSupportedException fırlatılır. Belgelerdeki tablodan özet:

İşlemSQLite desteği
AddColumn, CreateIndex, CreateTable, DropIndex, DropTableDoğrudan destekleniyor
RenameColumn, RenameTableDoğrudan destekleniyor
AlterColumn, DropColumnRebuild ile
AddForeignKey, DropForeignKeyRebuild ile
AddPrimaryKey, DropPrimaryKeyRebuild ile
AddUniqueConstraint, DropUniqueConstraintRebuild ile
AddCheckConstraint, DropCheckConstraint, RenameIndexRebuild ile
EnsureSchema, DropSchemaHiçbir şey yapmaz (no-op)
Insert, Update, DeleteDestekleniyor

Rebuild'in kapsamadığı durumlar için migration içinde migrationBuilder.Sql ile rebuild adımlarını elle yazabilirsiniz; belgeler ayrıntı için SQLite'ın kendi ALTER TABLE belgelerine yönlendirir. Migration özelleştirme ayrı yazıda anlatılıyor.

Idempotent script ve migration kilidi

SQLite'ta prosedürel bir dil olmadığı için idempotent migration script'lerinin gerektirdiği koşullu mantık üretilemez. Veritabanına uygulanan son migration'ı biliyorsanız o migration'dan başlayan bir script üretin; bilmiyorsanız belgeler dotnet ef database update kullanmayı ve veritabanı dosyasını bağlantıyla belirtmeyi önerir:

bash
dotnet ef migrations script CurrentMigration
dotnet ef database update --connection "Data Source=My.db"

EF Core 9 ile gelen migration kilidi SQLite'ta farklı çalışır. SQL Server bağlantı kapanınca otomatik bırakılan bir oturum kilidi kullanırken, SQLite'ta yerleşik uygulama kilidi olmadığından EF Core bir __EFMigrationsLock tablosu oluşturup bir satır ekleyerek kilit alır. Süreç migration sırasında öldürülürse satır kalabilir ve sonraki her migration denemesi kilidin bırakılmasını süresiz bekler. Çözüm tabloyu düşürmek veya satırlarını silmektir; tablo gerektiğinde otomatik olarak yeniden oluşturulur:

sql
DELETE FROM "__EFMigrationsLock";

InMemory sağlayıcısı: production için değil

InMemory sağlayıcısı EF Core'u bellek içinde çalışan bir veritabanıyla kullanmanızı sağlar. Belgeler bu sağlayıcı hakkında çok nettir: performans veya sağlamlık için tasarlanmamıştır, test ortamları dışında kullanılmamalıdır ve production kullanımı için tasarlanmamıştır. Daha da önemlisi, sağlayıcıya artık yeni özellik eklenmiyor. Bazı kullanıcılar onu test için kullansa da belgeler bunu da önermez ve sağlayıcı sayfası InMemory ile testi anlatan bölüme “önerilmez” notuyla bağlantı verir. Test için önerilen yaklaşımlar, gerçek veritabanıyla test ve SQLite bellek içi modu dahil, EF Core test yazma yazısında anlatılıyor.

Azure Cosmos DB sağlayıcısı: ilişkisel değil, doküman veritabanı

Azure Cosmos DB sağlayıcısı: ilişkisel değil, doküman veritabanı: Şema olmadığı için migration desteklenmez; container'ları oluşturmak için..., Aynı nedenle scaffold (tersine...

Cosmos DB sağlayıcısı yalnızca Azure Cosmos DB for NoSQL ile çalışır ve UseCosmos ile yapılandırılır. EF Core 9'da sağlayıcı üzerinde kapsamlı çalışma yapıldı ve bir dizi yüksek etkili kırıcı değişiklik geldi; eski bir uygulamayı yükseltiyorsanız EF Core 9 kırıcı değişiklik notlarının Cosmos bölümünü dikkatle okuyun. Belgeler Cosmos DB'nin bir doküman veritabanı olduğunu ve EF Core'un ilişkisel veritabanlarıyla aradaki farkları gizlemeye çalışmadığını vurgular. Bu yüzden ilişkisel sağlayıcılarda alıştığınız bazı şeyler burada yoktur:

  • Şema olmadığı için migration desteklenmez; container'ları oluşturmak için EnsureCreatedAsync kullanılır ve belgelere göre bu çağrı normal çalışma sırasında değil yalnızca deploy sırasında yapılmalıdır.
  • Aynı nedenle scaffold (tersine mühendislik) desteklenmez.
  • Modelde tanımlanan index ve kısıt gibi şema kavramları yok sayılır.
  • İlişkisel tarzda transaction'lar ve birden çok işlem üzerinde tam ACID garantileri yoktur; sağlayıcı mümkün olduğunda transactional batch kullanır.
  • Farklı dokümanlardaki ilişkili entity grafiklerini yüklemek desteklenmez; veri genellikle denormalize edilir.
  • Cosmos DB SDK senkron G/Ç desteklemediği için EF Core 9 ve sonrasında ToList veya SaveChanges gibi senkron API'ler istisna fırlatır; her zaman asenkron metotları kullanın. Async kullanımı için EF Core async yazısına bakın.

Birden fazla sağlayıcıyla çalışmak

Bazı projeler geliştirmede SQLite, production'da SQL Server kullanmak ister. EF Core araçları migration'ı yalnızca etkin sağlayıcı için ürettiğinden bu durumda her sağlayıcı için ayrı bir migration seti tutmanız gerekir; nasıl yapılacağı migration özelleştirme yazısında anlatılıyor. Bir sağlayıcı için üretilmiş migration'ları başka bir sağlayıcıyla uygulamak desteklenmeyen bir senaryodur ve EF Core 9 sonrası bekleyen model değişikliği hatasına yol açabilir. Ayrıca yukarıdaki SQLite sınırlamaları nedeniyle bir sorgu ya da migration SQLite'ta farklı davranabilir; production'da kullanacağınız sağlayıcıyla test etmek bu sürprizleri azaltır.

Seçim için kısa rehber

  • Windows sunucu ve Microsoft ekosistemi: SQL Server sağlayıcısı EF Core projesinin parçasıdır; uyumluluk düzeyini açıkça ayarlayın. Barındırma tarafı için Windows hosting rehberi.
  • Tek dosyalık gömülü veritabanı, masaüstü, küçük araçlar: SQLite; migration sınırlamalarını ve idempotent script eksikliğini baştan bilin.
  • PostgreSQL, MySQL veya MariaDB: Belgelerdeki tabloda listelenen üçüncü taraf sağlayıcılar (Npgsql, Pomelo, Oracle'ın MySQL sağlayıcısı); EF Core 10 desteğini sağlayıcının kendi belgelerinden doğrulayın.
  • Testler: InMemory yerine test yazısındaki yaklaşımlar.
  • Şemasız doküman verisi: Cosmos DB sağlayıcısı; migration ve scaffold olmadan, yalnızca asenkron API'lerle.

Sık Sorulan Sorular

EF Core 10 ile PostgreSQL kullanabilir miyim?

PostgreSQL sağlayıcısı Npgsql ekibi tarafından geliştirilir. Bu yazının dayandığı belge sürümündeki tabloda Npgsql satırında EF Core 8 ve 9 yazıyor; EF Core 10 desteği için Npgsql'in kendi belgelerine ve NuGet sayfasına bakmanız gerekir. Sağlayıcıların ana sürümler arasında genellikle çalışmadığını unutmayın.

SQLite'ta kolon silen bir migration neden başarısız oluyor?

SQLite DropColumn işlemini EF Core'un yaptığı tablo rebuild'i ile destekler. Rebuild yalnızca EF modelinin parçası olan nesneler için çalışır; migration içinde elle oluşturduğunuz bir nesne söz konusuysa NotSupportedException alırsınız. Bu durumda rebuild adımlarını migrationBuilder.Sql ile elle yazmanız gerekir.

UseSqlServer ile UseAzureSql arasındaki fark nedir?

Belgeler Azure SQL'e bağlanırken UseSqlServer yerine UseAzureSql kullanmanızı önerir. Bu metot EF Core 9 ile geldi, Azure SQL'e uygun bağlantı dayanıklılığı ayarlarını otomatik kurar ve EF Core 10'da JSON verisi için yeni json tipinin varsayılan olarak kullanılmasını sağlar.

InMemory sağlayıcısıyla test yazmak yanlış mı?

Belgeler InMemory'yi test için kullanmayı önermez ve sağlayıcıya yeni özellik eklenmediğini belirtir. Gerçek veritabanıyla test veya SQLite bellek içi modu gibi alternatifler test yazısında karşılaştırılıyor.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: EF Core öğrenme rehberi · EF Core kurulumu ve NuGet paketleri · Birden fazla sağlayıcıyla migration · EF Core test yazma · SQL Server nedir · SQLite nedir · PostgreSQL nedir