EFEF Core Handbook

TEMEL

Primary Key Yapılandırması

Her tablonun bir primary key'i olmalıdır. EF Core, Id veya <EntityName>Id adlı property'yi otomatik PK olarak algılar. Farklı bir yapı istiyorsan (composite key, GUID, identity kontrolü) Fluent API ile belirtirsin.

Veritabanı sağlayıcısı Bu sayfadaki eşleşen örnekleri seçilen sağlayıcıya göre gösterir.

Fluent API

// Tek kolon PK
builder.HasKey(p => p.Id);

// Composite (bileşik) PK
builder.HasKey(p => new { p.OrderId, p.ProductId });

// Alternatif anahtar (Unique Constraint)
builder.HasAlternateKey(p => p.Sku);
builder.HasAlternateKey(p => new { p.TenantId, p.Code });

// Identity / Key generation
builder.Property(p => p.Id)
       .ValueGeneratedOnAdd();           // IDENTITY (varsayılan int/long için)

builder.Property(p => p.Id)
       .ValueGeneratedNever();           // Uygulama atar

builder.Property(p => p.UpdatedAt)
       .ValueGeneratedOnAddOrUpdate();   // Genelde rowversion / timestamp ile

// GUID — EF Core 8: UUID v7 (sıralı, index dostu)
builder.Property(p => p.Id)
       .HasDefaultValueSql("NEWSEQUENTIALID()");   // SQL Server

SQL Karşılığı:

-- Tek kolon PK + IDENTITY
CREATE TABLE [Products] (
    [Id] INT IDENTITY(1,1) NOT NULL,
    CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED ([Id])
);

-- Composite PK (IDENTITY yok — uygulama atar)
CREATE TABLE [OrderProducts] (
    [OrderId]   INT NOT NULL,
    [ProductId] INT NOT NULL,
    CONSTRAINT [PK_OrderProducts] PRIMARY KEY CLUSTERED ([OrderId], [ProductId])
);

-- Alternate Key = UNIQUE CONSTRAINT
ALTER TABLE [Products]
ADD CONSTRAINT [AK_Products_Sku] UNIQUE ([Sku]);

-- GUID ile NEWSEQUENTIALID
CREATE TABLE [Products] (
    [Id] UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID(),
    CONSTRAINT [PK_Products] PRIMARY KEY NONCLUSTERED ([Id])
);
-- Tek kolon PK + IDENTITY
CREATE TABLE products (
    id   INT GENERATED ALWAYS AS IDENTITY,
    CONSTRAINT pk_products PRIMARY KEY (id)
);

-- Composite PK
CREATE TABLE order_products (
    order_id   INT NOT NULL,
    product_id INT NOT NULL,
    CONSTRAINT pk_order_products PRIMARY KEY (order_id, product_id)
);

-- Alternate Key = UNIQUE CONSTRAINT
ALTER TABLE products
ADD CONSTRAINT ak_products_sku UNIQUE (sku);

-- UUID
CREATE TABLE products (
    id   UUID NOT NULL DEFAULT gen_random_uuid(),
    CONSTRAINT pk_products PRIMARY KEY (id)
);
// PostgreSQL PK stratejileri
builder.Property(p => p.Id)
       .UseIdentityAlwaysColumn();              // GENERATED ALWAYS AS IDENTITY

builder.Property(p => p.Id)
       .UseIdentityByDefaultColumn();           // GENERATED BY DEFAULT AS IDENTITY (override edilebilir)

// UUID kullanımı (PostgreSQL native uuid tipi)
builder.Property(p => p.Id)
       .HasColumnType("uuid")
       .HasDefaultValueSql("gen_random_uuid()"); // PG 13+

Ne zaman ne kullanılır?

Senaryo Key Tipi
Genel CRUD uygulaması int + IDENTITY
Dağıtık sistem / Microservice Guid / UUID
Dışarıdan gelen veri (import) ValueGeneratedNever
Ara tablo (join entity) Composite PK

PostgreSQL UUID notu: gen_random_uuid() sıralı değildir → B-tree index fragmentation'a dikkat. Alternatif: UUIDv7 (uygulama tarafında üretilen sıralı UUID, EF Core 8+ ile NewGuid() override).