Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Atrybuty mapowania służą do modyfikowania lub zastępowania konfiguracji wykrytej przez konwencje tworzenia modelu. Konfiguracja wykonywana przez atrybuty mapowania może zostać zastąpiona przez interfejs API tworzenia modelu używany w programie OnModelCreating.
Ważne
Ten dokument obejmuje tylko atrybuty mapowania w kontekście konfiguracji relacji. Inne zastosowania atrybutów mapowania zostały omówione w odpowiednich sekcjach szerszej dokumentacji modelowania.
Wskazówka
Poniższy kod można znaleźć w MappingAttributes.cs.
Gdzie uzyskać atrybuty mapowania
Wiele atrybutów mapowania pochodzi z przestrzeni nazw System.ComponentModel.DataAnnotations i System.ComponentModel.DataAnnotations.Schema . Atrybuty w tych przestrzeniach nazw są uwzględniane w ramach platformy podstawowej we wszystkich obsługiwanych wersjach platformy .NET, dlatego nie wymagają instalacji żadnych dodatkowych pakietów NuGet. Te atrybuty mapowania są często nazywane "adnotacjami danych" i są używane przez różne struktury, w tym EF Core, EF6, ASP.NET Core MVC itd. Są one również używane do walidacji.
Korzystanie z adnotacji danych w wielu technologiach oraz mapowanie i walidacja doprowadziło do różnic w semantyce między technologiami. Wszystkie nowe atrybuty mapowania przeznaczone wyłącznie dla EF Core są teraz proste i przejrzyste w swojej semantyce i użyciu. Te atrybuty znajdują się w pakiecie NuGet Microsoft.EntityFrameworkCore.Abstractions . Ten pakiet jest dołączany jako zależność za każdym razem, gdy jest używany główny pakiet Microsoft.EntityFrameworkCore lub jeden ze skojarzonych pakietów dostawcy bazy danych. Jednak pakiet Abstrakcji jest lekkim pakietem, do którego można odwoływać się bezpośrednio za pomocą kodu aplikacji, bez wprowadzania całego EF Core i jej zależności.
RequiredAttribute
RequiredAttribute jest stosowane do właściwości, aby wskazać, że nie może być null. W kontekście relacji [Required] jest zwykle używany dla właściwości klucza obcego. Dzięki temu klucz obcy nie może przyjmować wartości null, co sprawia, że relacja jest wymagana. Na przykład, w przypadku następujących typów, właściwość Post.BlogId jest oznaczona jako nienulowalna, a relacja staje się obowiązkowa.
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
[Required]
public string BlogId { get; set; }
public Blog Blog { get; init; }
}
Uwaga
W przypadku używania typów odwołań dopuszczających wartość null w języku C#, właściwość w tym przykładzie jest już bezwartościowa, co oznacza, że atrybut nie będzie miał żadnego wpływu.
[Required] umieszczony na nawigacji zależnej ma taki sam efekt. Oznacza to, że klucz obcy jest niezerowalny, co oznacza, że relacja jest wymagana. Na przykład:
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
public string BlogId { get; set; }
[Required]
public Blog Blog { get; init; }
}
Jeśli [Required] znajduje się na nawigacji zależnej, a właściwość klucza obcego jest w stanie cieniowym, to właściwość cieniowa jest ustawiona jako niepusta, co sprawia, że relacja jest obowiązkowa. Na przykład:
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
[Required]
public Blog Blog { get; init; }
}
Uwaga
Korzystanie z [Required] po stronie głównej nawigacji relacji nie ma żadnego wpływu.
ForeignKeyAttribute
ForeignKeyAttribute służy do łączenia właściwości klucza obcego z jego nawigacjami.
[ForeignKey] można umieścić we właściwości klucza obcego, której nazwa odpowiada nawigacji zależnej. Na przykład:
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
[ForeignKey(nameof(Blog))]
public string BlogKey { get; set; }
public Blog Blog { get; init; }
}
Lub, [ForeignKey] można umieścić na nawigacji zależnej lub głównej z nazwą właściwości, która ma być używana jako klucz obcy. Na przykład:
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
public string BlogKey { get; set; }
[ForeignKey(nameof(BlogKey))]
public Blog Blog { get; init; }
}
Gdy [ForeignKey] zostanie umieszczony na nawigacji, a podana nazwa nie jest zgodna z żadną nazwą właściwości, zostanie utworzona właściwość w tle o tej nazwie, która będzie pełnić rolę klucza obcego. Na przykład:
public class Blog
{
public string Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
[ForeignKey("BlogKey")]
public Blog Blog { get; init; }
}
InversePropertyAttribute
InversePropertyAttribute służy do łączenia nawigacji z jej odwrotnym powiązaniem. Na przykład w następujących typach jednostek istnieją dwie relacje między Blog i Post. Bez żadnej konfiguracji konwencje EF nie mogą określić, które nawigacje między dwoma typami powinny być sparowane. Dodanie [InverseProperty] do jednej z sparowanych nawigacji rozwiązuje tę niejednoznaczność i umożliwia programowi EF tworzenie modelu.
public class Blog
{
public int Id { get; set; }
[InverseProperty("Blog")]
public List<Post> Posts { get; } = new();
public int FeaturedPostId { get; set; }
public Post FeaturedPost { get; set; }
}
public class Post
{
public int Id { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; init; }
}
Ważne
[InverseProperty] jest wymagana tylko wtedy, gdy istnieje więcej niż jedna relacja między tymi samymi typami. W przypadku pojedynczej relacji dwie nawigacje są automatycznie sparowane.
DeleteBehaviorAttribute
Zgodnie z konwencją EF używa ClientSetNullDeleteBehavior dla relacji opcjonalnych i zachowania Cascade dla relacji wymaganych. Można to zmienić, umieszczając element DeleteBehaviorAttribute w jednej z nawigacji relacji. Na przykład:
public class Blog
{
public int Id { get; set; }
public List<Post> Posts { get; } = new();
}
public class Post
{
public int Id { get; set; }
public int BlogId { get; set; }
[DeleteBehavior(DeleteBehavior.Restrict)]
public Blog Blog { get; init; }
}
Aby uzyskać więcej informacji na temat zachowań kaskadowych, sprawdź Usuwanie kaskadowe.