Właściwości jednostki

Każdy typ jednostki w modelu ma zestaw właściwości, które program EF Core odczytuje i zapisuje z bazy danych. Jeśli używasz relacyjnej bazy danych, właściwości jednostki są mapowe na kolumny tabeli.

Uwzględnione i wykluczone właściwości

Zgodnie z konwencją wszystkie właściwości publiczne z elementem getter i setter zostaną uwzględnione w modelu.

Określone właściwości można wykluczyć w następujący sposób:

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

    [NotMapped]
    public DateTime LoadedFromDatabase { get; set; }
}

Nazwy kolumn

Zgodnie z konwencją podczas korzystania z relacyjnej bazy danych właściwości jednostki są mapowane na kolumny tabeli o takiej samej nazwie jak właściwość.

Jeśli wolisz skonfigurować kolumny o różnych nazwach, możesz to zrobić jako następujący fragment kodu:

public class Blog
{
    [Column("blog_id")]
    public int BlogId { get; set; }

    public string Url { get; set; }
}

Typy danych w kolumnach

W przypadku korzystania z relacyjnej bazy danych dostawca bazy danych wybiera typ danych na podstawie typu platformy .NET właściwości. Uwzględnia również inne metadane, takie jak skonfigurowana maksymalna długość, czy właściwość jest częścią klucza podstawowego itp.

Na przykład program SQL Server mapuje DateTime właściwości na datetime2(7) kolumny i string właściwości na nvarchar(max) kolumny (lub nvarchar(450) dla właściwości, które są używane jako klucz).

Możesz również skonfigurować kolumny, aby określić dokładny typ danych dla kolumny. Na przykład poniższy kod konfiguruje Url jako ciąg inny niż Unicode o maksymalnej długości 200 i Rating jako dziesiętny z dokładnością 5 i skalą 2:

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

    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }

    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
}

Długość maksymalna

Skonfigurowanie maksymalnej długości zapewnia dostawcy bazy danych wskazówkę dotyczącą odpowiedniego typu danych kolumny do wyboru dla danej właściwości. Maksymalna długość dotyczy tylko typów danych tablicy, takich jak string i byte[].

Uwaga

Program Entity Framework nie wykonuje żadnej weryfikacji maksymalnej długości przed przekazaniem danych do dostawcy. Do dostawcy lub magazynu danych należy sprawdzić, czy jest to odpowiednie. Na przykład w przypadku określania wartości docelowej dla programu SQL Server przekroczenie maksymalnej długości spowoduje wyjątek, ponieważ typ danych bazowej kolumny nie pozwoli na przechowywanie nadmiarowych danych.

W poniższym przykładzie skonfigurowanie maksymalnej długości 500 spowoduje utworzenie kolumny typu nvarchar(500) w programie SQL Server:

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

    [MaxLength(500)]
    public string Url { get; set; }
}

Precyzja i skala

Niektóre typy danych relacyjnych obsługują aspekty dokładności i skalowania; określają, jakie wartości można przechowywać, oraz ilość miejsca potrzebnego do magazynowania w kolumnie. Typy danych obsługują precyzję i skalowanie jest zależne od bazy danych, ale w większości baz danych decimal i DateTime typów obsługują te aspekty. W przypadku decimal właściwości precyzja definiuje maksymalną liczbę cyfr potrzebnych do wyrażenia dowolnej wartości, która będzie zawierać kolumna, a skala definiuje maksymalną wymaganą liczbę miejsc dziesiętnych. W przypadku DateTime właściwości precyzja definiuje maksymalną liczbę cyfr potrzebnych do wyrażenia ułamków sekund, a skala nie jest używana.

Uwaga

Program Entity Framework nie wykonuje żadnej walidacji dokładności ani skali przed przekazaniem danych do dostawcy. Do dostawcy lub magazynu danych należy sprawdzić poprawność zgodnie z potrzebami. Na przykład w przypadku określania wartości docelowej dla programu SQL Server kolumna typu datetime danych nie zezwala na ustawienie dokładności, podczas gdy może datetime2 mieć precyzję z zakresu od 0 do 7 włącznie.

W poniższym przykładzie skonfigurowanie Score właściwości o dokładności 14 i skali 2 spowoduje utworzenie kolumny typu decimal(14,2) w programie SQL Server, a skonfigurowanie LastUpdated właściwości z dokładnością 3 spowoduje kolumnę typu datetime2(3):

public class Blog
{
    public int BlogId { get; set; }
    [Precision(14, 2)]
    public decimal Score { get; set; }
    [Precision(3)]
    public DateTime LastUpdated { get; set; }
}

Skalowanie nigdy nie jest definiowane bez uprzedniego zdefiniowania precyzji, więc adnotacja danych do definiowania skali to [Precision(precision, scale)].

Unicode

W niektórych relacyjnych bazach danych istnieją różne typy reprezentujące dane tekstowe Unicode i inne niż Unicode. Na przykład w programie SQL Server nvarchar(x) służy do reprezentowania danych Unicode w formacie UTF-16, natomiast varchar(x) służy do reprezentowania danych innych niż Unicode (ale zobacz uwagi dotyczące obsługi protokołu UTF-8 programu SQL Server). W przypadku baz danych, które nie obsługują tej koncepcji, skonfigurowanie tej koncepcji nie ma żadnego wpływu.

Właściwości tekstu są domyślnie konfigurowane jako Unicode. Możesz skonfigurować kolumnę jako inną niż Unicode w następujący sposób:

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }

    [Unicode(false)]
    [MaxLength(22)]
    public string Isbn { get; set; }
}

Wymagane i opcjonalne właściwości

Właściwość jest uważana za opcjonalną, jeśli jest prawidłowa, aby zawierała nullwartość . Jeśli null nie jest prawidłową wartością, która ma być przypisana do właściwości, jest uważana za wymaganą właściwość. Podczas mapowania do schematu relacyjnej bazy danych wymagane właściwości są tworzone jako kolumny bez wartości null, a opcjonalne właściwości są tworzone jako kolumny dopuszczane do wartości null.

Konwencje

Zgodnie z konwencją właściwość, której typ platformy .NET może zawierać wartość null, zostanie skonfigurowana jako opcjonalna, natomiast właściwości, których typ platformy .NET nie może zawierać wartości null, zostaną skonfigurowane zgodnie z wymaganiami. Na przykład wszystkie właściwości z typami wartości .NET (int, decimal, boolitp.) są konfigurowane zgodnie z wymaganiami, a wszystkie właściwości z typami wartości null .NET (int?, decimal?, bool?itp.) są konfigurowane jako opcjonalne.

W języku C# 8 wprowadzono nową funkcję o nazwie typy referencyjne dopuszczające wartość null (NRT), która umożliwia dodawanie adnotacji do typów odwołań, wskazującą, czy są one prawidłowe, aby zawierały wartości null, czy nie. Ta funkcja jest domyślnie włączona w nowych szablonach projektów, ale pozostaje wyłączona w istniejących projektach, chyba że jawnie została wybrana. Typy referencyjne dopuszczane do wartości null wpływają na zachowanie programu EF Core w następujący sposób:

  • Jeśli typy odwołań dopuszczane do wartości null są wyłączone, wszystkie właściwości z typami referencyjnymi platformy .NET są konfigurowane jako opcjonalne zgodnie z konwencją (na przykład string).
  • Jeśli typy odwołań dopuszczane do wartości null są włączone, właściwości zostaną skonfigurowane na podstawie wartości null języka C# typu .NET: string? zostaną skonfigurowane jako opcjonalne, ale string zostaną skonfigurowane zgodnie z wymaganiami.

W poniższym przykładzie przedstawiono typ jednostki z wymaganymi i opcjonalnymi właściwościami z wyłączoną funkcją odwołania dopuszczalnego wartości null i włączoną:

public class CustomerWithoutNullableReferenceTypes
{
    public int Id { get; set; }

    [Required] // Data annotations needed to configure as required
    public string FirstName { get; set; }

    [Required] // Data annotations needed to configure as required
    public string LastName { get; set; }

    public string MiddleName { get; set; } // Optional by convention
}

Używanie typów odwołań dopuszczanych do wartości null jest zalecane, ponieważ przepływa wartość null wyrażoną w kodzie języka C# do modelu i bazy danych platformy EF Core oraz nie pozwala na dwukrotne wyrażenie tego samego pojęcia przy użyciu interfejsu API Fluent lub adnotacji danych.

Uwaga

Zachowaj ostrożność podczas włączania typów odwołań dopuszczających wartość null w istniejącym projekcie: właściwości typu odwołania, które zostały wcześniej skonfigurowane jako opcjonalne, będą teraz konfigurowane zgodnie z wymaganiami, chyba że są jawnie oznaczone jako dopuszczające wartość null. Podczas zarządzania schematem relacyjnej bazy danych może to spowodować wygenerowanie migracji, które zmieniają wartość null kolumny bazy danych.

Aby uzyskać więcej informacji na temat typów referencyjnych dopuszczanych do wartości null i sposobu ich używania z programem EF Core, zobacz dedykowaną stronę dokumentacji dla tej funkcji.

Jawna konfiguracja

Właściwość, która byłaby opcjonalna zgodnie z konwencją, może być wymagana w następujący sposób:

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

    [Required]
    public string Url { get; set; }
}

Sortowania kolumn

Sortowanie można zdefiniować w kolumnach tekstowych, określając sposób ich porównywania i porządkowania. Na przykład poniższy fragment kodu konfiguruje kolumnę programu SQL Server tak, aby nie uwzględniała wielkości liter:

modelBuilder.Entity<Customer>().Property(c => c.Name)
    .UseCollation("SQL_Latin1_General_CP1_CI_AS");

Jeśli wszystkie kolumny w bazie danych muszą używać określonego sortowania, zdefiniuj sortowanie na poziomie bazy danych.

Ogólne informacje o obsłudze sortowania programu EF Core można znaleźć na stronie dokumentacji sortowania.

Komentarze kolumn

Możesz ustawić dowolny komentarz tekstowy ustawiony w kolumnie bazy danych, co umożliwia dokumentowanie schematu w bazie danych:

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

    [Comment("The URL of the blog")]
    public string Url { get; set; }
}

Kolejność kolumn

Domyślnie podczas tworzenia tabeli z elementami Migrations program EF Core zamawia najpierw kolumny klucza podstawowego, a następnie właściwości typu jednostki i typów należących do nich, a na koniec właściwości z typów podstawowych. Można jednak określić inną kolejność kolumn:

public class EntityBase
{
    [Column(Order = 0)]
    public int Id { get; set; }
}

public class PersonBase : EntityBase
{
    [Column(Order = 1)]
    public string FirstName { get; set; }

    [Column(Order = 2)]
    public string LastName { get; set; }
}

public class Employee : PersonBase
{
    public string Department { get; set; }
    public decimal AnnualSalary { get; set; }
}

Interfejs API Fluent może służyć do zastępowania kolejności wykonywanej za pomocą atrybutów, w tym rozwiązywania konfliktów, gdy atrybuty na różnych właściwościach określają ten sam numer zamówienia.

Należy pamiętać, że w ogólnym przypadku większość baz danych obsługuje tylko porządkowanie kolumn podczas tworzenia tabeli. Oznacza to, że atrybut order kolumny nie może być używany do ponownego porządkownia kolumn w istniejącej tabeli.