REFERANS
Provider Uyumluluğu — SQL Server, PostgreSQL, Oracle, SQLite
EF Core'un Fluent API'sinin %90'ı provider-agnostic çalışır. Ancak bazı özellikler (Temporal Tables, JSON sütun syntax'ı, index tipleri) provider'a özgüdür.
Ortak (Tüm Provider'larda Çalışan) API
// Bunlar HER YERDE çalışır — SQL Server, PostgreSQL, SQLite, Oracle, MySQL...
builder.HasKey(p => p.Id);
builder.HasIndex(p => p.Email).IsUnique();
builder.Property(p => p.Name).IsRequired().HasMaxLength(200);
builder.HasOne(p => p.Category).WithMany(c => c.Products).HasForeignKey(p => p.CategoryId);
builder.OwnsOne(p => p.Address);
builder.HasQueryFilter(p => !p.IsDeleted);
builder.ToTable("Products");
builder.HasData(...);
builder.Ignore(p => p.Computed);
Provider-Specific Farklılıklar
PK Üretimi (Auto-Increment)
// Fluent API aynı — oluşan SQL farklı:
builder.Property(p => p.Id).ValueGeneratedOnAdd();
| Provider |
SQL Çıktısı |
| SQL Server |
INT IDENTITY(1,1) |
| PostgreSQL |
INT GENERATED ALWAYS AS IDENTITY veya SERIAL |
| SQLite |
INTEGER PRIMARY KEY AUTOINCREMENT |
| Oracle |
NUMBER GENERATED ALWAYS AS IDENTITY |
| MySQL |
INT AUTO_INCREMENT |
String / Unicode Davranışı
| Provider |
IsUnicode(true) |
IsUnicode(false) |
Varsayılan |
| SQL Server |
NVARCHAR |
VARCHAR |
NVARCHAR |
| PostgreSQL |
TEXT (hep Unicode) |
TEXT (fark yok) |
TEXT |
| SQLite |
TEXT (hep Unicode) |
TEXT (fark yok) |
TEXT |
| Oracle |
NVARCHAR2 |
VARCHAR2 |
VARCHAR2 |
| MySQL |
VARCHAR (charset'e bağlı) |
VARCHAR |
utf8mb4 ile |
JSON Columns
// Fluent API aynı:
builder.OwnsOne(p => p.Metadata, m => m.ToJson());
| Provider |
Destek |
SQL Tipi |
LINQ-to-JSON |
| SQL Server |
EF Core 7+ |
NVARCHAR(MAX) |
Full |
| PostgreSQL (Npgsql) |
EF Core 7+ |
jsonb |
Full + extra ops |
| SQLite |
|
— |
— |
| Oracle |
21c+ kısıtlı |
JSON |
Kısıtlı |
| MySQL (Pomelo) |
8.0+ |
JSON |
Temel |
Temporal Tables
| Provider |
Native Destek |
Alternatif |
| SQL Server |
IsTemporal() |
— |
| PostgreSQL |
|
Trigger-based audit tablolar veya pgAudit eklentisi |
| SQLite |
|
Uygulama seviyesinde audit log |
| Oracle |
Flashback |
FLASHBACK TABLE (farklı API) |
Sequences & HiLo
modelBuilder.HasSequence<int>("OrderNumbers").StartsAt(1000);
builder.Property(o => o.OrderNo).HasDefaultValueSql("NEXT VALUE FOR OrderNumbers");
| Provider |
Sequence |
HiLo |
| SQL Server |
|
|
| PostgreSQL |
|
|
| SQLite |
|
|
| Oracle |
|
|
| MySQL |
|
|
EF.Functions Farklılıkları
| Fonksiyon |
SQL Server |
PostgreSQL (Npgsql) |
SQLite |
Like |
LIKE |
LIKE / ILIKE |
LIKE |
DateDiffDay |
DATEDIFF |
(kullan: date - date) |
|
Contains (FTS) |
CONTAINS |
(kullan: EF.Functions.ToTsVector) |
|
Random |
NEWID() |
random() |
random() |
Collate |
|
|
|
ILike (case-insensitive) |
|
(Npgsql özel) |
|
JsonContains |
|
(Npgsql özel) |
|
PostgreSQL Özel — Npgsql Provider
// NuGet: Npgsql.EntityFrameworkCore.PostgreSQL
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(connectionString));
// PostgreSQL'e özgü özellikler
builder.Property(p => p.Tags).HasColumnType("text[]"); // Native array
builder.Property(p => p.SearchVector).HasColumnType("tsvector"); // Full-text
builder.Property(p => p.Location).HasColumnType("point"); // Geometric
builder.HasIndex(p => p.Name).HasMethod("gin"); // GIN index
builder.Property(p => p.Data).HasColumnType("jsonb"); // Binary JSON
// ILIKE (case-insensitive like — PostgreSQL'e özel)
var results = context.Products
.Where(p => EF.Functions.ILike(p.Name, "%telefon%"))
.ToListAsync();
Oracle Özel
// NuGet: Oracle.EntityFrameworkCore
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseOracle(connectionString));
// Oracle kısıtları
// - Tablo adı max 128 karakter (eski: 30)
// - NVARCHAR2 max 2000 byte
// - Boolean → NUMBER(1) olarak saklanır
builder.Property(p => p.Name).HasMaxLength(200); // NVARCHAR2(200)
builder.Property(p => p.IsActive); // NUMBER(1)
MySQL Özel (Pomelo)
// NuGet: Pomelo.EntityFrameworkCore.MySql
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
// MySQL'e özgü
builder.Property(p => p.Name).HasCharSet("utf8mb4");
builder.ToTable(t => t.HasCharSet("utf8mb4"));
Provider Seçimi Pratik Rehber
| Senaryo |
Önerilen Provider |
Neden |
| Enterprise / Kurumsal |
SQL Server veya Oracle |
Temporal tables, row-level security, lisans desteği |
| Startup / SaaS |
PostgreSQL |
Ücretsiz, JSON native, array, FTS güçlü |
| Embedded / Mobil |
SQLite |
Dosya tabanlı, sıfır kurulum |
| Legacy sistem |
MySQL |
Yaygın hosting desteği |
| Çoklu DB desteği gerekli |
Fluent API + provider-agnostic kal |
EF.Functions yerine LINQ kullan |
Altın kural: Eğer birden fazla provider desteklenecekse, provider-specific API'lerden (EF.Functions.DateDiff, IsTemporal, HasMethod) kaçınılmalı ve saf Fluent API + LINQ ile kalınmalı.