Schlüssel

Ein Schlüssel dient als eindeutiger Bezeichner für eine einzelne Entitätsinstanz. Die meisten Entitäten in EF verfügen über einen einzelnen Schlüssel, der dem Konzept eines Primärschlüssels in relationalen Datenbanken zugeordnet ist (für Entitäten ohne Schlüssel siehe Schlüssellose Entitäten). Entitäten können über den Primärschlüssel hinaus weitere Schlüssel besitzen (weitere Informationen erhalten Sie unter Alternative Schlüssel).

Konfigurieren eines Primärschlüssels

Per Konvention wird eine Eigenschaft mit dem Namen Id oder <type name>Id als Primärschlüssel einer Entität konfiguriert.

internal class Car
{
    public string Id { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

internal class Truck
{
    public string TruckId { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Hinweis

Nicht eigenständige Entitätstypen nutzen verschiedene Regeln zum Definieren von Schlüsseln.

Sie können eine einzelne Eigenschaft wie folgt so konfigurieren, dass sie der Primärschlüssel einer Entität ist:

internal class Car
{
    [Key]
    public string LicensePlate { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Sie können auch mehrere Eigenschaften so konfigurieren, dass sie der Schlüssel einer Entität sind – dies wird als zusammengesetzter Schlüssel bezeichnet. Konventionen richten nur in bestimmten Fällen einen zusammengesetzten Schlüssel ein, z. B. für eine nicht eigenständige Typsammlung.

Hinweis

Dieses [PrimaryKey]-Attribut wurde in EF Core 7.0 eingeführt. Verwenden Sie in älteren Versionen die Fluent-API.

[PrimaryKey(nameof(State), nameof(LicensePlate))]
internal class Car
{
    public string State { get; set; }
    public string LicensePlate { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Wertschöpfung

Bei nicht zusammengesetzten numerischen und GUID-Primärschlüsseln richtet EF Core per Konvention die Wertgenerierung für Sie ein. Beispielsweise wird ein numerischer Primärschlüssel in SQL Server automatisch als IDENTITY-Spalte eingerichtet. Weitere Informationen erhalten Sie in der Dokumentation zur Wertgenerierung und dem Leitfaden für spezifische Vererbungsmappingstrategien.

Name des Primärschlüssels

Per Konvention werden in relationalen Datenbanken Primärschlüssel mit dem Namen PK_<type name> erstellt. Sie können den Namen der Primärschlüsseleinschränkung wie folgt konfigurieren:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasKey(b => b.BlogId)
        .HasName("PrimaryKey_BlogId");
}

Schlüsseltypen und Werte

Während EF Core die Verwendung von Eigenschaften jeglicher einfachen Typen als Primärschlüssel unterstützt, unter anderem string, Guid, byte[], unterstützen nicht alle Datenbanken alle Typen als Schlüssel. In einigen Fällen können die Schlüsselwerte automatisch in einen unterstützten Typ konvertiert werden, andernfalls sollte die Konvertierung manuell angegeben werden.

Schlüsseleigenschaften müssen beim Hinzufügen einer neuen Entität zum Kontext immer einen Nicht-Standardwert aufweisen, aber einige Typen werden von der Datenbank generiert. In diesem Fall versucht EF, einen temporären Wert zu generieren, wenn die Entität zu Nachverfolgungszwecken hinzugefügt wird. Nachdem SaveChanges aufgerufen wird, wird der temporäre Wert durch den von der Datenbank generierten Wert ersetzt.

Wichtig

Wenn beim Hinzufügen einer Entität der Wert einer Schlüsseleigenschaft von der Datenbank generiert und ein nicht standardmäßiger Wert angegeben wird, geht EF davon aus, dass die Entität bereits in der Datenbank vorhanden ist, und versucht, sie zu aktualisieren, anstatt eine neue einzufügen. Um dies zu vermeiden, deaktivieren Sie die Wertgenerierung, oder lesen Sie wie explizite Werte für generierte Eigenschaften angegeben werden.

Alternativschlüssel

Ein alternativer Schlüssel dient zusätzlich zum Primärschlüssel als alternativer eindeutiger Bezeichner für jede Entitätsinstanz; er kann als Ziel einer Beziehung verwendet werden. Bei Verwendung einer relationalen Datenbank entspricht dies dem Konzept eines eindeutigen Index bzw. einer eindeutigen Einschränkung für die alternativen Schlüsselspalten und eine oder mehrere Fremdschlüsseleinschränkungen, die auf die Spalte(n) verweisen.

Tipp

Wenn Sie nur die Eindeutigkeit für eine Spalte erzwingen möchten, definieren Sie einen eindeutigen Index anstelle eines alternativen Schlüssels (siehe Indizes). In EF sind alternative Schlüssel schreibgeschützt und liefern zusätzliche Semantik über eindeutige Indizes, da sie als Ziel eines Fremdschlüssels verwendet werden können.

Alternative Schlüssel werden in der Regel bei Bedarf für Sie eingeführt, und Sie müssen sie nicht manuell konfigurieren. Per Konvention wird ein alternativer Schlüssel für Sie eingeführt, wenn Sie eine Eigenschaft identifizieren, die nicht der Primärschlüssel als Ziel einer Beziehung ist.

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.BlogUrl)
            .HasPrincipalKey(b => b.Url);
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public string BlogUrl { get; set; }
    public Blog Blog { get; set; }
}

Sie können auch eine einzelne Eigenschaft als alternativen Schlüssel konfigurieren:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => c.LicensePlate);
}

Sie können auch mehrere Eigenschaften als alternativen Schlüssel konfigurieren (bezeichnet als zusammengesetzter Schlüssel):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => new { c.State, c.LicensePlate });
}

Schließlich werden der Index und die Einschränkung, die für einen alternativen Schlüssel eingeführt werden, per Konvention AK_<type name>_<property name> genannt (für zusammengesetzte alternative Schlüssel wird <property name> zu einer durch Unterstrich getrennten Liste von Eigenschaftsnamen). Sie können den Namen des Indexes und der eindeutigen Einschränkung des alternativen Schlüssels konfigurieren:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => c.LicensePlate)
        .HasName("AlternateKey_LicensePlate");
}