Klucze
Klucz służy jako unikatowy identyfikator dla każdego wystąpienia jednostki. Większość jednostek w programie EF ma jeden klucz, który mapuje na koncepcję klucza podstawowego w relacyjnych bazach danych (w przypadku jednostek bez kluczy zobacz Jednostki bez klucza). Jednostki mogą mieć dodatkowe klucze wykraczające poza klucz podstawowy (zobacz Klucze alternatywne, aby uzyskać więcej informacji).
Konfigurowanie klucza podstawowego
Zgodnie z konwencją właściwość o nazwie Id
lub <type name>Id
zostanie skonfigurowana jako klucz podstawowy jednostki.
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; }
}
Uwaga
Typy jednostek należących używają różnych reguł do definiowania kluczy.
Można skonfigurować pojedynczą właściwość jako klucz podstawowy jednostki w następujący sposób:
internal class Car
{
[Key]
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
Można również skonfigurować wiele właściwości jako klucza jednostki — jest to nazywane kluczem złożonym. Konwencje będą konfigurować tylko klucz złożony w określonych przypadkach — na przykład w przypadku kolekcji typów należących do firmy.
Uwaga
Atrybut [PrimaryKey]
został wprowadzony w programie EF Core 7.0. Użyj interfejsu API Fluent w starszych wersjach.
[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; }
}
Generowanie wartości
W przypadku kluczy podstawowych bez złożonych liczb i identyfikatorów GUID program EF Core konfiguruje generowanie wartości zgodnie z konwencją. Na przykład klucz podstawowy liczbowy w programie SQL Server jest automatycznie konfigurowany jako kolumna IDENTITY. Aby uzyskać więcej informacji, zobacz dokumentację dotyczącą generowania wartości i wskazówki dotyczące określonych strategii mapowania dziedziczenia.
Nazwa klucza podstawowego
Zgodnie z konwencją klucze podstawowe relacyjnych baz danych są tworzone z nazwą PK_<type name>
. Nazwę ograniczenia klucza podstawowego można skonfigurować w następujący sposób:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasKey(b => b.BlogId)
.HasName("PrimaryKey_BlogId");
}
Typy kluczy i wartości
Chociaż program EF Core obsługuje używanie właściwości dowolnego typu pierwotnego jako klucza podstawowego, w tym string
, Guid
byte[]
i innych, nie wszystkie bazy danych obsługują wszystkie typy jako klucze. W niektórych przypadkach wartości klucza można przekonwertować na obsługiwany typ automatycznie, w przeciwnym razie konwersja powinna zostać określona ręcznie.
Właściwości klucza muszą zawsze mieć wartość inną niż domyślna podczas dodawania nowej jednostki do kontekstu, ale niektóre typy będą generowane przez bazę danych. W takim przypadku program EF spróbuje wygenerować wartość tymczasową, gdy jednostka zostanie dodana do celów śledzenia. Po wywołaniu funkcji SaveChanges wartość tymczasowa zostanie zamieniona przez wartość wygenerowaną przez bazę danych.
Ważne
Jeśli właściwość klucza ma swoją wartość wygenerowaną przez bazę danych, a wartość nie domyślna zostanie określona podczas dodawania jednostki, program EF przyjmie, że jednostka już istnieje w bazie danych i spróbuje ją zaktualizować zamiast wstawić nową. Aby tego uniknąć, wyłącz generowanie wartości lub zobacz , jak określić jawne wartości dla wygenerowanych właściwości.
Klucze alternatywne
Alternatywny klucz służy jako alternatywny unikatowy identyfikator dla każdego wystąpienia jednostki oprócz klucza podstawowego; może służyć jako element docelowy relacji. W przypadku korzystania z relacyjnej bazy danych ta mapuje koncepcję unikatowego indeksu/ograniczenia w kolumnach klucza alternatywnego i co najmniej jednego ograniczenia klucza obcego odwołującego się do kolumn.
Napiwek
Jeśli chcesz tylko wymusić unikatowość w kolumnie, zdefiniuj unikatowy indeks zamiast klucza alternatywnego (zobacz Indeksy). W programie EF klucze alternatywne są tylko do odczytu i zapewniają dodatkową semantykę dla unikatowych indeksów, ponieważ mogą być używane jako element docelowy klucza obcego.
Klucze alternatywne są zwykle wprowadzane w razie potrzeby i nie trzeba ich konfigurować ręcznie. Zgodnie z konwencją klucz alternatywny jest wprowadzany podczas identyfikowania właściwości, która nie jest kluczem podstawowym jako elementem docelowym relacji.
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; }
}
Można również skonfigurować pojedynczą właściwość jako klucz alternatywny:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate);
}
Można również skonfigurować wiele właściwości jako klucz alternatywny (nazywany złożonym kluczem alternatywnym):
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => new { c.State, c.LicensePlate });
}
Na koniec zgodnie z konwencją indeks i ograniczenie wprowadzone dla klucza alternatywnego zostaną nazwane AK_<type name>_<property name>
(w przypadku złożonych kluczy <property name>
alternatywnych staje się podkreślona oddzielona lista nazw właściwości). Możesz skonfigurować nazwę indeksu klucza alternatywnego i unikatowe ograniczenie:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate)
.HasName("AlternateKey_LicensePlate");
}