Übung: Einrichten einer Migration
In dieser Lerneinheit erstellen Sie C#-Entitätsklassen, die Tabellen in einer lokalen SQLite-Datenbank zugeordnet werden. Das EF Core-Migrationsfeature erstellt Tabellen aus diesen Entitäten.
Eine Migration bietet eine Möglichkeit, das Datenbankschema inkrementell zu aktualisieren.
Abrufen der Projektdateien
Rufen Sie zunächst die Projektdateien ab. Es gibt verschiedene Möglichkeiten, die Projektdateien abzurufen:
- Verwenden von GitHub Codespaces
- Klonen des GitHub-Repositorys
Wenn Sie eine kompatible Containerruntime installiert haben, können Sie auch die Dev Containers-Erweiterung verwenden, um das Repository in einem Container mit vorinstallierten Tools zu öffnen.
Verwenden von GitHub Codespaces
Ein Codespace ist eine in der Cloud gehostete IDE. Wenn Sie GitHub Codespaces verwenden, wechseln Sie zum Repository in Ihrem Browser. Wählen Sie Code aus, und erstellen Sie dann einen neuen Codespace im main
-Branch.
Klonen des GitHub-Repositorys
Wenn Sie GitHub Codespaces nicht verwenden, können Sie das GitHub-Projektrepository klonen und die Dateien dann als Ordner in Visual Studio Code öffnen.
Öffnen Sie ein Befehlsterminal, und klonen Sie dann das Projekt aus GitHub mithilfe der Eingabeaufforderung:
git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
Wechseln Sie zum Ordner mslearn-persist-data-ef-core, und öffnen Sie dann das Projekt in Visual Studio Code:
cd mslearn-persist-data-ef-core code .
Überprüfen des Codes
Nun verfügen Sie über die Projektdateien, mit denen Sie arbeiten können. Sehen Sie sich an, was im Projekt enthalten ist, und überprüfen Sie den Code.
- Das Projekt ist eine ASP.NET Core-Web-API, die sich im Verzeichnis ContosoPizza befindet. Die Dateipfade, auf die in diesem Modul verwiesen wird, sind relativ zum ContosoPizza-Verzeichnis.
- Services/PizzaService.cs ist eine Dienstklasse, die CRUD-Methoden definiert. Alle Methoden lösen zurzeit eine
System.NotImplementedException
aus. - In Program.cs ist
PizzaService
über das Abhängigkeitsinjektionssystem von ASP.NET Core registriert. - Controllers/PizzaController.cs ist ein Wert für
ApiController
, der einen Endpunkt für die HTTP-Verben „POST“, „GET“, „PUT“ und „DELETE“ verfügbar macht. Diese Verben rufen die entsprechenden CRUD-Methoden fürPizzaService
auf.PizzaService
wird in den KonstruktorPizzaController
eingefügt. - Der Ordner Models enthält die Modelle, die von
PizzaService
undPizzaController
verwendet werden. - Die Entitätsmodelle Pizza.cs, Topping.cs und Sauce.cs weisen die folgenden Beziehungen auf:
- Eine Pizza kann mit einer oder mehreren Zutaten belegt sein.
- Ein Belag kann auf einer oder mehreren Pizzas verwendet werden.
- Eine Pizza kann nur eine Soße aufweisen, aber eine Soße kann auf vielen Pizzas verwendet werden.
Erstellen der App
Gehen Sie wie folgt vor, um die App in Visual Studio Code zu erstellen:
Klicken Sie im Bereich Explorer mit der rechten Maustaste auf das Verzeichnis ContosoPizza, und wählen Sie In integriertem Terminal öffnen aus.
Dadurch wird ein Terminalbereich für das Verzeichnis ContosoPizza geöffnet.
Verwenden Sie den folgenden Befehl, um die App zu erstellen:
dotnet build
Der Code sollte ohne Warnungen oder Fehler erstellt werden.
Hinzufügen von NuGet-Paketen und EF Core-Tools
Die Datenbank-Engine, mit der Sie in diesem Modul arbeiten, ist SQLite. SQLite ist eine schlanke, dateibasierte Datenbank-Engine. Sie eignet sich gut für Entwicklung und Tests, aber auch für kleine Produktionsbereitstellungen.
Hinweis
Wie bereits erwähnt, können Datenbankanbieter in EF Core ergänzt werden. SQLite ist eine gute Wahl für dieses Modul, da es schlank und plattformübergreifend ist. Sie können denselben Code verwenden, um verschiedene andere Datenbank-Engines wie SQL Server und PostgreSQL zu verwenden. Sie können sogar mehrere Datenbank-Engines in derselben App verwenden.
Bevor Sie beginnen, fügen Sie die erforderlichen Pakete hinzu:
Führen Sie im Terminalbereich den folgenden Befehl aus:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
Dieser Befehl fügt das NuGet-Paket hinzu, das den EF Core-SQLite-Datenbankanbieter und alle zugehörigen Abhängigkeiten enthält, einschließlich der allgemeinen EF Core-Dienste.
Führen Sie den folgenden Befehl aus:
dotnet add package Microsoft.EntityFrameworkCore.Design
Dieser Befehl fügt Pakete hinzu, die für die EF Core-Tools erforderlich sind.
Führen Sie zum Abschluss den folgenden Befehl aus:
dotnet tool install --global dotnet-ef
Dieser Befehl installiert
dotnet ef
, das Tool, mit dem Sie Migrationen und Gerüstbau erstellen.Tipp
Wenn
dotnet ef
bereits installiert ist, können Sie dieses Tool aktualisieren, indem Siedotnet tool update --global dotnet-ef
ausführen.
Modellgerüste und DbContext
Jetzt fügen Sie eine DbContext
-Implementierung hinzu und konfigurieren diese. DbContext
ist ein Gateway, über das Sie mit der Datenbank interagieren können.
Klicken Sie mit der rechten Maustaste auf das Verzeichnis ContosoPizza, und fügen Sie einen neuen Ordner namens Data hinzu.
Erstellen Sie im Ordner Data eine neue Datei namens PizzaContext.cs. Fügen Sie der leeren Datei den folgenden Code hinzu:
using Microsoft.EntityFrameworkCore; using ContosoPizza.Models; namespace ContosoPizza.Data; public class PizzaContext : DbContext { public PizzaContext (DbContextOptions<PizzaContext> options) : base(options) { } public DbSet<Pizza> Pizzas => Set<Pizza>(); public DbSet<Topping> Toppings => Set<Topping>(); public DbSet<Sauce> Sauces => Set<Sauce>(); }
Für den Code oben gilt:
- Der Konstruktor akzeptiert einen Parameter vom Typ
DbContextOptions<PizzaContext>
. Durch den Konstruktor kann externer Code an die Konfiguration übergeben werden, sodass dasselbeDbContext
-Element von Test- und Produktionscode gemeinsam genutzt und sogar mit verschiedenen Anbietern verwendet werden kann. - Die
DbSet<T>
-Eigenschaften entsprechen Tabellen, die in der Datenbank erstellt werden sollen. - Die Tabellennamen stimmen mit den Eigenschaftsnamen
DbSet<T>
in der KlassePizzaContext
überein. Sie können dieses Verhalten bei Bedarf außer Kraft setzen. - Bei Instanziierung macht
PizzaContext
die EigenschaftenPizzas
,Toppings
undSauces
verfügbar. Änderungen, die Sie an den von diesen Eigenschaften verfügbar gemachten Sammlungen vornehmen, werden an die Datenbank weitergegeben.
- Der Konstruktor akzeptiert einen Parameter vom Typ
Ersetzen Sie
// Add the PizzaContext
in der Datei Program.cs durch den folgenden Code:builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");
Der obige Code:
PizzaContext
wird mit dem ASP.NET Core-Abhängigkeitsinjektionssystem registriert.- Gibt an, dass
PizzaContext
den SQLite-Datenbankanbieter verwenden soll. - Definiert eine SQLite-Verbindungszeichenfolge, die auf die lokale Datei ContosoPizza.db verweist.
Hinweis
Da SQLite lokale Datenbankdateien verwendet, stellt die Hartcodierung der Verbindungszeichenfolge wahrscheinlich kein Problem dar. Für Netzwerkdatenbanken wie PostgreSQL und SQL Server sollten Sie Ihre Verbindungszeichenfolgen grundsätzlich sicher speichern. Verwenden Sie für die lokale Entwicklung den Secret Manager. Bei Produktionsbereitstellungen sollten Sie einen Dienst wie Azure Key Vault in Betracht ziehen.
Ersetzen Sie zudem
// Additional using declarations
in der Datei Program.cs durch den folgenden Code.using ContosoPizza.Data;
Dieser Code löst Abhängigkeiten aus dem vorherigen Schritt auf.
Speichern Sie alle Änderungen. GitHub Codespaces speichert Ihre Änderungen automatisch.
Erstellen Sie die App im Terminal, indem Sie
dotnet build
ausführen. Der Buildvorgang sollte erfolgreich und ohne Warnungen oder Fehler abgeschlossen werden.
Erstellen und Ausführen einer Migration
Als Nächstes erstellen Sie eine Migration, mit der Sie Ihre anfängliche Datenbank erstellen können.
Führen Sie den folgenden Befehl aus, um eine Migration zum Erstellen der Datenbanktabellen zu generieren:
dotnet ef migrations add InitialCreate --context PizzaContext
Für den obigen Befehl gilt Folgendes:
- Die Migration erhält den Namen InitialCreate.
- Die Option
--context
gibt den Namen der Klasse im Projekt ContosoPizza an, der vonDbContext
abgeleitet wird.
Im Projektstamm ContosoPizza wird ein neues Verzeichnis Migrations angezeigt. Das Verzeichnis enthält die Datei <timestamp>_InitialCreate.cs, die Datenbankänderungen beschreibt, die in ein Datendefinitionssprache-Änderungsskript (Data Definition Language, DDL) übersetzt werden sollen.
Führen Sie den folgenden Befehl aus, um die Migration InitialCreate anzuwenden:
dotnet ef database update --context PizzaContext
Mit diesem Befehl wird die Migration angewendet. Da ContosoPizza.db nicht vorhanden ist, wird die Migration im Projektverzeichnis erstellt.
Tipp
Das
dotnet ef
-Tool wird auf allen Plattformen unterstützt. In Visual Studio unter Windows können Sie die PowerShell-CmdletsAdd-Migration
undUpdate-Database
im integrierten Fenster der Paket-Manager-Konsole verwenden.
Untersuchen der Datenbank
EF Core hat eine Datenbank für Ihre App erstellt. Sehen Sie sich nun die Datenbank mithilfe der SQLite-Erweiterung genauer an.
Klicken Sie im Bereich Explorer mit der rechten Maustaste auf die Datei ContosoPizza.db, und wählen Sie Datenbank öffnen aus.
Im Explorer-Bereich wird der Ordner SQLite Explorer angezeigt.
Wählen Sie den Ordner SQLite Explorer aus, um den Knoten und alle untergeordneten Knoten zu erweitern. Klicken Sie mit der rechten Maustaste auf ContosoPizza.db, und wählen Sie Tabelle „sqlite_master“ anzeigen aus, um das vollständige Datenbankschema und die Einschränkungen anzuzeigen, die von der Migration erstellt wurden.
- Es wurden Tabellen erstellt, die den einzelnen Entitäten entsprechen.
- Tabellennamen wurden aus den Namen der
DbSet
-Eigenschaften fürPizzaContext
entnommen. - Eigenschaften namens
Id
wurden als automatisch inkrementierte Primärschlüsselfelder abgeleitet. - Die Namenskonventionen für Primärschlüssel- und Fremdschlüsseleinschränkungen von EF Core sind
PK_<primary key property>
bzw.FK_<dependent entity>_<principal entity>_<foreign key property>
. Die Platzhalter<dependent entity>
und<principal entity>
entsprechen den Namen der Entitätsklasse.
Hinweis
Wie ASP.NET Core MVC verwendet EF Core einen Konvention-vor-Konfiguration-Ansatz. EF Core-Konventionen verkürzen die Entwicklungszeit, indem sie auf die Absicht des Entwicklers schließen. So wird beispielsweise aus einer Eigenschaft namens
Id
oder<entity name>Id
abgeleitet, dass sie der Primärschlüssel der generierten Tabelle ist. Wenn Sie die Benennungskonvention nicht übernehmen möchten, muss die Eigenschaft mit dem Attribut[Key]
oder als Schlüssel in derOnModelCreating
-Methode vonDbContext
konfiguriert werden.
Ändern des Modells und Aktualisieren des Datenbankschemas
Ihre Vorgesetzten bei Contoso Pizza nennen Ihnen einige neue Anforderungen, weshalb Sie Ihre Entitätsmodelle ändern müssen. In den folgenden Schritten ändern Sie die Modelle mithilfe von Zuordnungsattributen (manchmal auch als Datenanmerkungen bezeichnet).
Nehmen Sie in Models\Pizza.cs die folgenden Änderungen vor:
- Fügen Sie eine
using
-Anweisung fürSystem.ComponentModel.DataAnnotations
hinzu. - Fügen Sie vor der
Name
-Eigenschaft ein[Required]
-Attribut hinzu, um die Eigenschaft als erforderlich zu markieren. - Fügen Sie vor der
Name
-Eigenschaft ein[MaxLength(100)]
-Attribut hinzu, um eine maximale Zeichenfolgenlänge von 100 anzugeben.
using System.ComponentModel.DataAnnotations; namespace ContosoPizza.Models; public class Pizza { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public Sauce? Sauce { get; set; } public ICollection<Topping>? Toppings { get; set; } }
- Fügen Sie eine
Nehmen Sie in Models\Sauce.cs die folgenden Änderungen vor:
- Fügen Sie eine
using
-Anweisung fürSystem.ComponentModel.DataAnnotations
hinzu. - Fügen Sie vor der
Name
-Eigenschaft ein[Required]
-Attribut hinzu, um die Eigenschaft als erforderlich zu markieren. - Fügen Sie vor der
Name
-Eigenschaft ein[MaxLength(100)]
-Attribut hinzu, um eine maximale Zeichenfolgenlänge von 100 anzugeben. - Fügen Sie eine
bool
-Eigenschaft namensIsVegan
hinzu.
using System.ComponentModel.DataAnnotations; namespace ContosoPizza.Models; public class Sauce { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public bool IsVegan { get; set; } }
- Fügen Sie eine
Nehmen Sie in Models\Topping.cs die folgenden Änderungen vor:
- Fügen Sie
using
-Anweisungen fürSystem.ComponentModel.DataAnnotations
undSystem.Text.Json.Serialization
hinzu. - Fügen Sie vor der
Name
-Eigenschaft ein[Required]
-Attribut hinzu, um die Eigenschaft als erforderlich zu markieren. - Fügen Sie vor der
Name
-Eigenschaft ein[MaxLength(100)]
-Attribut hinzu, um eine maximale Zeichenfolgenlänge von 100 anzugeben. - Fügen Sie eine
decimal
-Eigenschaft namensCalories
unmittelbar nach derName
-Eigenschaft hinzu. - Fügen Sie eine
Pizzas
-Eigenschaft vom TypICollection<Pizza>?
hinzu, um ausPizza
-Topping
eine m:n-Beziehung zu machen. - Fügen Sie der
Pizzas
-Eigenschaft ein[JsonIgnore]
-Attribut hinzu.
Wichtig
Durch diese Schritte wird verhindert, dass
Topping
-Entitäten diePizzas
-Eigenschaft einschließen, wenn der Web-API-Code die Antwort in JSON serialisiert. Ohne diese Änderung würde eine serialisierte Sammlung von Belägen eine Sammlung mit jeder Pizza enthalten, die den jeweiligen Belag verwendet. Jede Pizza in dieser Auflistung enthielte wiederum eine Auflistung von Belägen, die jeweils wieder eine Auflistung von Pizzas umfassen würde. Diese Art von Endlosschleife wird als Zirkelbezug bezeichnet und kann nicht serialisiert werden.using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace ContosoPizza.Models; public class Topping { public int Id { get; set; } [Required] [MaxLength(100)] public string? Name { get; set; } public decimal Calories { get; set; } [JsonIgnore] public ICollection<Pizza>? Pizzas { get; set; } }
- Fügen Sie
Speichern Sie alle Änderungen, und führen Sie
dotnet build
aus.Führen Sie den folgenden Befehl aus, um eine Migration zum Erstellen der Datenbanktabellen zu generieren:
dotnet ef migrations add ModelRevisions --context PizzaContext
Eine Migration namens ModelRevisions wird erstellt.
Hinweis
Folgende Meldung wird angezeigt: Ein Vorgang wurde geplant, der zum Verlust von Daten führen kann. Überprüfen Sie die Migration auf Genauigkeit. Die Meldung wird angezeigt, da Sie die Beziehung von
Pizza
mitTopping
von 1:n in m:n geändert haben, was erfordert, dass eine vorhandene Fremdschlüsselspalte gelöscht wird. Da in Ihrer Datenbank noch keine Daten vorhanden sind, ist diese Änderung nicht problematisch. Im Allgemeinen empfiehlt es sich jedoch, die generierte Migration zu überprüfen, wenn diese Warnung angezeigt wird. So können Sie sicherstellen, dass durch die Migration keine Daten gelöscht oder abgeschnitten werden.Führen Sie den folgenden Befehl aus, um die Migration ModelRevisions anzuwenden:
dotnet ef database update --context PizzaContext
Klicken Sie auf der Titelleiste des Ordners SQLite Explorer auf die Schaltfläche Datenbanken aktualisieren.
Klicken Sie im Ordner SQLite Explorer mit der rechten Maustaste auf ContosoPizza.db. Wählen Sie Tabelle „sqlite_master“ anzeigen aus, um das vollständige Datenbankschema und die Einschränkungen anzuzeigen.
Wichtig
Die SQLite-Erweiterung verwendet geöffnete SQLite-Registerkarten erneut.
- Eine Jointabelle
PizzaTopping
wurde erstellt, um die m:n-Beziehung zwischen Pizzas und Belägen darzustellen. Toppings
undSauces
wurden neue Felder hinzugefügt.Calories
wird alstext
-Spalte definiert, weil SQLite keinen entsprechendendecimal
-Typ aufweist.- In ähnlicher Weise wird
IsVegan
alsinteger
-Spalte definiert. SQLite definiert keinenbool
-Typ. - In beiden Fällen verwaltet EF Core die Übersetzung.
- Die
Name
-Spalte in jeder Tabelle wurde alsnot null
markiert, SQLite weist jedoch keineMaxLength
-Einschränkung auf.
Tipp
EF Core-Datenbankanbieter ordnen den Features einer bestimmten Datenbank ein Modellschema zu. Im Gegensatz zu anderen Datenbanken wie SQL Server und PostgreSQL implementiert SQLite keine entsprechende Einschränkung für
MaxLength
.- Eine Jointabelle
Klicken Sie im Ordner SQLite Explorer mit der rechten Maustaste auf die Tabelle
_EFMigrationsHistory
, und wählen Sie Tabelle anzeigen aus. Die Tabelle enthält eine Liste aller Migrationen, die auf die Datenbank angewendet werden. Da Sie zwei Migrationsvorgänge ausgeführt haben, gibt es zwei Einträge: einen für die InitialCreate-Migration und einen zweiten für ModelRevisions.
Hinweis
In dieser Übung wurden Zuordnungsattribute (Datenanmerkungen) verwendet, um der Datenbank Modelle zuzuordnen. Alternativ zum Zuordnen von Attributen können Sie die Fluent-API „ModelBuilder“ verwenden, um Modelle zu konfigurieren. Beide Ansätze sind möglich, aber einige Entwickler*innen bevorzugen einen der beiden Ansätze.
Sie haben Migrationen verwendet, um ein Datenbankschema zu definieren und zu aktualisieren. In der nächsten Einheit stellen Sie die Methoden zur Datenbearbeitung in PizzaService
fertig.