Entitätseigenschaften
Jeder Entitätstyp in Ihrem Modell verfügt über eine Reihe von Eigenschaften, die EF Core aus der Datenbank liest und schreibt. Wenn Sie eine relationale Datenbank verwenden, entsprechen die Eigenschaften von Entitäten den Spalten der Tabellen.
Eingeschlossene und ausgeschlossene Eigenschaften
Standardmäßig werden alle öffentlichen Eigenschaften mit einem Getter und einem Setter in das Modell eingeschlossen.
Bestimmte Eigenschaften können wie folgt ausgeschlossen werden:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[NotMapped]
public DateTime LoadedFromDatabase { get; set; }
}
Spaltennamen
In der Konvention werden Entitätseigenschaften bei Verwendung einer relationalen Datenbank Tabellenspalten zugeordnet, die denselben Namen wie die Eigenschaft aufweisen.
Wenn Sie Ihre Spalten lieber mit unterschiedlichen Namen konfigurieren möchten, können Sie dies wie den folgenden Codeausschnitt tun:
public class Blog
{
[Column("blog_id")]
public int BlogId { get; set; }
public string Url { get; set; }
}
Spaltendatentypen
Bei Verwendung einer relationalen Datenbank wählt der Datenbankanbieter einen Datentyp basierend auf dem .NET-Typ der Eigenschaft aus. Außerdem werden andere Metadaten berücksichtigt, z. B. die konfigurierte maximale Länge, ob die Eigenschaft Teil eines Primärschlüssels ist usw.
Der SQL Server-Anbieter ordnet z. B. DateTime
-Eigenschaften zu datetime2(7)
-Spalten zu und string
-Eigenschaften zu nvarchar(max)
-Spalten zu (oder zu nvarchar(450)
bei Eigenschaften, die als Schlüssel verwendet werden).
Sie können Ihre Spalten auch so konfigurieren, dass ein exakter Datentyp für eine Spalte angegeben wird. Der folgende Code konfiguriert z. B. Url
als Nicht-Unicode-Zeichenfolge mit maximaler Länge von 200
und Rating
als Dezimalzahl mit Genauigkeit von 5
und Skalierung von 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; }
}
Maximale Länge
Das Konfigurieren einer maximalen Länge stellt dem Datenbankanbieter einen Hinweis auf den entsprechenden Spaltendatentyp bereit, der für eine bestimmte Eigenschaft ausgewählt werden soll. Die maximale Länge gilt nur für Arraydatentypen, z. B. string
und byte[]
.
Anmerkung
Entity Framework führt keine Überprüfung der maximalen Länge durch, bevor Daten an den Anbieter übergeben werden. Es ist Sache des Anbieters oder Datenspeichers, ggf. eine Überprüfung durchzuführen. Wenn Sie beispielsweise SQL Server als Ziel festlegen, führt die Überschreitung der maximalen Länge zu einer Ausnahme, da der Datentyp der zugrunde liegenden Spalte keine übermäßigen Daten speichern kann.
Im folgenden Beispiel wird beim Konfigurieren einer maximalen Länge von 500 eine Spalte vom Typ nvarchar(500)
auf SQL Server erstellt:
public class Blog
{
public int BlogId { get; set; }
[MaxLength(500)]
public string Url { get; set; }
}
Genauigkeit und Skalierung
Einige relationale Datentypen unterstützen die Genauigkeits- und Skalierungsaspekte; Diese steuern, welche Werte gespeichert werden können und wie viel Speicherplatz für die Spalte benötigt wird. Welche Datentypen Genauigkeit und Skalierung unterstützen, ist datenbankabhängig, aber in den meisten Datenbanken decimal
und DateTime
Typen unterstützen diese Facets. Bei decimal
-Eigenschaften definiert die Genauigkeit die maximale Anzahl von Ziffern, die zum Ausdrücken eines beliebigen Werts, den die Spalte enthält, erforderlich sind, und die Skalierung definiert die maximale Anzahl der benötigten Dezimalstellen. Bei DateTime
-Eigenschaften definiert die Genauigkeit die maximale Anzahl von Ziffern, die zum Ausdrücken von Sekundenbruchteilen erforderlich sind, und die Skalierung wird nicht verwendet.
Anmerkung
Entity Framework führt keine Überprüfung der Genauigkeit oder Skalierung durch, bevor Daten an den Anbieter übergeben werden. Es liegt in der Verantwortung des Anbieters oder Datenspeichers, gegebenenfalls zu validieren. Beispielsweise lässt sich für eine Spalte vom Datentyp datetime
unter SQL Server nicht die Genauigkeit einstellen, während datetime2
eine Genauigkeit zwischen 0 und 7 (einschließlich) haben kann.
Im folgenden Beispiel führt die Konfiguration der Score
-Eigenschaft mit Genauigkeit 14 und Skalierung 2 dazu, dass eine Spalte vom Typ decimal(14,2)
auf SQL Server erstellt wird, und das Konfigurieren der LastUpdated
-Eigenschaft mit Genauigkeit 3 führt zu einer Spalte vom Typ 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; }
}
Die Skalierung wird nie definiert, ohne zuerst die Genauigkeit zu definieren, sodass die Datenanmerkung zum Definieren der Skalierung [Precision(precision, scale)]
lautet.
Unicode
In einigen relationalen Datenbanken sind unterschiedliche Typen vorhanden, um Unicode- und Nicht-Unicode-Textdaten darzustellen. In SQL Server wird nvarchar(x)
beispielsweise verwendet, um Unicode-Daten in UTF-16 darzustellen, während varchar(x)
verwendet wird, um Nicht-Unicode-Daten darzustellen (siehe die Hinweise zu SQL Server UTF-8-Unterstützung). Für Datenbanken, die dieses Konzept nicht unterstützen, hat die Konfiguration keine Auswirkungen.
Texteigenschaften sind standardmäßig als Unicode konfiguriert. Sie können eine Spalte wie folgt als Nicht-Unicode konfigurieren:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
[Unicode(false)]
[MaxLength(22)]
public string Isbn { get; set; }
}
Erforderliche und optionale Eigenschaften
Eine Eigenschaft wird als optional betrachtet, wenn es zulässig ist, dass sie null
enthält. Wenn null
kein gültiger Wert ist, der einer Eigenschaft zugewiesen werden soll, wird er als erforderliche Eigenschaft betrachtet. Beim Zuordnen zu einem relationalen Datenbankschema werden erforderliche Eigenschaften als nicht Nullwerte zulassende Spalten und optionale Eigenschaften als Nullwerte zulassende Spalten erstellt.
Konventionen
Standardmäßig wird eine Eigenschaft, deren .NET-Typ null enthalten kann, als optional konfiguriert, wohingegen Eigenschaften, deren .NET-Typ nicht null enthalten kann, wie erforderlich konfiguriert werden. Beispielsweise werden alle Eigenschaften mit .NET-Werttypen (int
, decimal
, bool
usw.) wie erforderlich konfiguriert, und alle Eigenschaften mit nullablen .NET-Werttypen (int?
, decimal?
, bool?
usw.) sind optional konfiguriert.
C# 8 hat ein neues Feature namens Nullwerte zulassende Verweistypen (Nullable Reference Types, NRT) eingeführt, mit dem Verweistypen mit Anmerkungen versehen werden können, um anzugeben, ob sie Nullwerte enthalten können oder nicht. Dieses Feature ist in neuen Projektvorlagen standardmäßig aktiviert, bleibt aber in vorhandenen Projekten deaktiviert, es sei denn, es wurde explizit angemeldet. Nullwerte zulassende Verweistypen wirken sich auf das Verhalten von EF Core wie folgt aus:
- Wenn Nullwerte zulassende Verweistypen deaktiviert sind, werden alle Eigenschaften mit .NET-Verweistypen als optional gemäß Konvention konfiguriert (z. B
string
). - Wenn Nullwerte zulassende Verweistypen aktiviert sind, werden Eigenschaften auf der C#-NULL-Zulässigkeit ihres .NET-Typs basierend konfiguriert:
string?
wird als optional, aberstring
als erforderlich konfiguriert.
Das folgende Beispiel zeigt einen Entitätstyp mit erforderlichen und optionalen Eigenschaften, wobei das Nullverweisfeature deaktiviert und aktiviert ist:
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
}
Die Verwendung der Nullwerte zulassenden Verweistypen wird empfohlen, da sie die in C#-Code ausgedrückte Nullwert-Zulässigkeit in das Modell von EF Core und die Datenbank einfließen lässt und die Verwendung der Fluent-API oder Datenanmerkungen zum zweimaligen Ausdrücken desselben Konzepts vermeidet.
Anmerkung
Aktivieren Sie Nullwerte zulassende Verweistypen für ein vorhandenes Projekt mit Vorsicht: Zuvor als optional konfigurierte Verweistypeigenschaften werden jetzt als erforderlich konfiguriert, es sei denn, sie werden explizit als Nullwerte zulassend gekennzeichnet. Beim Verwalten eines relationalen Datenbankschemas kann dies dazu führen, dass Migrationen generiert werden, die die Nullbarkeit der Datenbankspalte ändern.
Weitere Informationen zu Nullwerte zulassenden Verweistypen und deren Verwendung mit EF Core finden Sie auf der dedizierten Dokumentationsseite für dieses Feature.
Explizite Konfiguration
Eine Eigenschaft, die üblicherweise optional ist, kann wie folgt erforderlich gemacht werden:
public class Blog
{
public int BlogId { get; set; }
[Required]
public string Url { get; set; }
}
Spaltensortierungen
Eine Sortierung kann für Textspalten definiert werden, um festzulegen, wie sie verglichen und angeordnet werden. Mit dem folgenden Codeschnipsel wird beispielsweise eine SQL Server-Spalte so konfiguriert, dass die Groß-/Kleinschreibung nicht beachtet wird:
modelBuilder.Entity<Customer>().Property(c => c.Name)
.UseCollation("SQL_Latin1_General_CP1_CI_AS");
Wenn alle Spalten in einer Datenbank eine bestimmte Sortierung verwenden müssen, definieren Sie stattdessen die Sortierung auf Datenbankebene.
Allgemeine Informationen zur EF Core-Unterstützung für Sortierungen finden Sie auf der Seite zur Sortierungsdokumentation.
Spaltenkommentare
Sie können einen beliebigen Textkommentar festlegen, der in der Datenbankspalte festgelegt wird, sodass Sie Ihr Schema in der Datenbank dokumentieren können:
public class Blog
{
public int BlogId { get; set; }
[Comment("The URL of the blog")]
public string Url { get; set; }
}
Spaltenreihenfolge
Standardmäßig werden beim Erstellen einer Tabelle mit Migrationen zuerst Primärschlüsselspalten sortiert, gefolgt von Eigenschaften des Entitätstyps und eigenen Typen und schließlich Eigenschaften aus Basistypen. Sie können jedoch eine andere Spaltenreihenfolge angeben:
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; }
}
Die Fluent-API kann verwendet werden, um die Sortierung mit Attributen außer Kraft zu setzen, einschließlich der Auflösung von Konflikten, wenn Attribute für unterschiedliche Eigenschaften dieselbe Bestellnummer angeben.
Beachten Sie, dass die meisten Datenbanken im Allgemeinen nur das Sortieren von Spalten unterstützen, wenn die Tabelle erstellt wird. Dies bedeutet, dass das Spaltenreihenfolge-Attribut nicht zum Erneuten Anordnen von Spalten in einer vorhandenen Tabelle verwendet werden kann.