Övning – Konfigurera en migrering
I den här lektionen skapar du C#-entitetsklasser som mappas till tabeller i en lokal SQLite-databas. Funktionen EF Core-migrering skapar tabeller från dessa entiteter.
En migrering är ett sätt att stegvis uppdatera databasschemat.
Hämta projektfilerna
Kom igång genom att hämta projektfilerna. Du har några alternativ för hur du hämtar projektfilerna:
- Använda GitHub Codespaces
- Klona GitHub-lagringsplatsen
Om du har en kompatibel containerkörning installerad kan du även använda Tillägget Dev Containers för att öppna lagringsplatsen i en container med verktygen förinstallerade.
Använda GitHub Codespaces
Ett kodområde är en IDE som finns i molnet. Om du använder GitHub Codespaces går du till lagringsplatsen i webbläsaren. Välj Kod och skapa sedan ett nytt kodområde i -grenen main
.
Klona GitHub-lagringsplatsen
Om du inte använder GitHub Codespaces kan du klona projektets GitHub-lagringsplats och sedan öppna filerna som en mapp i Visual Studio Code.
Öppna en kommandoterminal och klona sedan projektet från GitHub med hjälp av kommandotolken:
git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
Gå till mappen mslearn-persist-data-ef-core och öppna projektet i Visual Studio Code:
cd mslearn-persist-data-ef-core code .
Granska koden
Nu har du projektfilerna att arbeta med. Se vad som finns i projektet och granska koden.
- Projektet, ett ASP.NET Core webb-API, finns i katalogen ContosoPizza. De filsökvägar som refereras till i den här modulen är relativa till ContosoPizza-katalogen .
- Services/PizzaService.cs är en tjänstklass som definierar CRUD-metoder (create, read, update och delete). Alla metoder genererar
System.NotImplementedException
för närvarande . - I Program.cs
PizzaService
registreras med ASP.NET Core beroendeinmatningssystemet. - Controllers/PizzaController.cs är ett värde för
ApiController
som exponerar en slutpunkt för HTTP POST-, GET-, PUT- och DELETE-verb. Dessa verb anropar motsvarande CRUD-metoder påPizzaService
.PizzaService
matas in iPizzaController
konstruktorn. - Mappen Modeller innehåller de modeller som används av
PizzaService
ochPizzaController
. - Entitetsmodellerna Pizza.cs, Topping.cs och Sauce.cs har följande relationer:
- En pizza kan ha en eller flera pålägg.
- En topping kan användas på en eller flera pizzor.
- En pizza kan ha en sås, men en sås kan användas på många pizzor.
Skapa appen
Så här skapar du appen i Visual Studio Code:
Högerklicka på katalogen ContosoPizza i Explorer-fönstret och välj Öppna i integrerad terminal.
Ett terminalfönster som är begränsat till ContosoPizza-katalogen öppnas.
Skapa appen med hjälp av följande kommando:
dotnet build
Koden bör skapas utan varningar eller fel.
Lägga till NuGet-paket och EF Core-verktyg
Databasmotorn som du arbetar med i den här modulen är SQLite. SQLite är en enkel, filbaserad databasmotor. Det är ett bra val för utveckling och testning, och det är också ett bra val för småskaliga produktionsdistributioner.
Anteckning
Som tidigare nämnts är databasprovidrar i EF Core anslutningsbara. SQLite är ett bra alternativ för den här modulen eftersom den är enkel och plattformsoberoende. Du kan använda samma kod för att arbeta med olika databasmotorer, till exempel SQL Server och PostgreSQL. Du kan till och med använda flera databasmotorer i samma app.
Innan du börjar lägger du till de nödvändiga paketen:
Kör följande kommando i terminalfönstret:
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
Det här kommandot lägger till NuGet-paketet som innehåller EF Core SQLite-databasprovidern och alla dess beroenden, inklusive de vanliga EF Core-tjänsterna.
Kör följande kommando:
dotnet add package Microsoft.EntityFrameworkCore.Design
Det här kommandot lägger till paket som krävs för EF Core-verktygen.
Slutför genom att köra det här kommandot:
dotnet tool install --global dotnet-ef
Det här kommandot installerar
dotnet ef
, det verktyg som du använder för att skapa migreringar och autogenerering.Tips
Om
dotnet ef
redan är installerat kan du uppdatera det genom att köradotnet tool update --global dotnet-ef
.
Autogenerera modeller och DbContext
Nu lägger du till och konfigurerar en DbContext
implementering. DbContext
är en gateway som du kan interagera med databasen genom.
Högerklicka på katalogen ContosoPizza och lägg till en ny mapp med namnet Data.
I mappen Data skapar du en ny fil med namnet PizzaContext.cs. Lägg till följande kod i den tomma filen:
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>(); }
I koden ovan:
- Konstruktorn accepterar en parameter av typen
DbContextOptions<PizzaContext>
. Konstruktorn tillåter att extern kod skickar konfigurationen så att sammaDbContext
kan delas mellan test- och produktionskod och även användas med olika providers. - Egenskaperna
DbSet<T>
motsvarar tabeller som ska skapas i databasen. - Tabellnamnen matchar
DbSet<T>
-egenskapsnamnen i klassenPizzaContext
. Du kan åsidosätta det här beteendet om det behövs. - När instansieras
PizzaContext
exponerasPizzas
egenskaperna ,Toppings
ochSauces
. Ändringar som du gör i de samlingar som exponeras av dessa egenskaper kommer att spridas till databasen.
- Konstruktorn accepterar en parameter av typen
I Program.cs ersätter du
// Add the PizzaContext
med följande kod:builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");
Koden ovan:
PizzaContext
Registrerar med ASP.NET Core beroendeinmatningssystemet.- Anger att
PizzaContext
ska använda SQLite-databasprovidern. - Definierar en SQLite-anslutningssträng som pekar på en lokal fil, ContosoPizza.db.
Anteckning
SQLite använder lokala databasfiler, så det är förmodligen okej att hårdkoda anslutningssträngen. För nätverksdatabaser som PostgreSQL och SQL Server bör du alltid lagra anslutningssträngarna på ett säkert sätt. Använd Secret Manager för lokal utveckling. Överväg att använda en tjänst som Azure Key Vault för produktionsdistributioner.
Ersätt även i Program.cs
// Additional using declarations
med följande kod.using ContosoPizza.Data;
Den här koden löser beroenden i föregående steg.
Spara alla ändringar. GitHub Codespaces sparar ändringarna automatiskt.
Skapa appen i terminalen genom att köra
dotnet build
. Bygget bör lyckas utan varningar eller fel.
Skapa och köra en migrering
Skapa sedan en migrering som du kan använda för att skapa din första databas.
Kör följande kommando för att skapa en migrering för generering av databastabellerna:
dotnet ef migrations add InitialCreate --context PizzaContext
I kommandot ovan:
- Migreringen ges namnet InitialCreate.
- Alternativet
--context
anger namnet på klassen i projektet ContosoPizza, som härleds frånDbContext
.
En ny Migrations-katalog visas i ContosoPizza-projektroten. Katalogen innehåller en <timestamp>_InitialCreate.cs fil som beskriver databasändringarna som ska översättas till ett DDL-ändringsskript (Data Definition Language).
Tillämpa InitialCreate-migreringen genom att köra följande kommando:
dotnet ef database update --context PizzaContext
Det här kommandot tillämpar migreringen. ContosoPizza.db finns inte, så migreringen skapas i projektkatalogen.
Tips
dotnet ef
-verktyget stöds på alla plattformar. I Visual Studio i Windows kan du användaAdd-Migration
powershell-cmdletarna ochUpdate-Database
i det integrerade package manager-konsolfönstret .
Granska databasen
EF Core skapade en databas för din app. Ta sedan en titt i databasen med hjälp av SQLite-tillägget.
Högerklicka på filen ContosoPizza.db i Explorer-fönstret och välj Öppna databas.
En SQLite Explorer-mapp visas i Explorer-fönstret .
Välj mappen SQLite Explorer för att expandera noden och alla dess underordnade noder. Högerklicka på ContosoPizza.db och välj Visa tabell sqlite_master för att visa det fullständiga databasschemat och begränsningarna som migreringen skapade.
- Tabeller som motsvarar varje entitet skapades.
- Tabellnamn hämtades från namnen
DbSet
på egenskaperna påPizzaContext
. - Egenskaper med namnet
Id
härleddes som autoincrementing av primärnyckelfält. - Namngivningskonventionerna för EF Core-primärnyckel och sekundärnyckelvillkor är
PK_<primary key property>
respektiveFK_<dependent entity>_<principal entity>_<foreign key property>
. Platshållarna<dependent entity>
och<principal entity>
motsvarar namnen på entitetsklasser.
Anteckning
Precis som ASP.NET Core MVC använder EF Core en konvention över konfigurationsmetod. EF Core-konventioner förkortar utvecklingstiden genom att tolka utvecklarens avsikt. Exempelvis tolkas en egenskap med namnet
Id
eller<entity name>Id
som den genererade tabellens primärnyckel. Om du väljer att inte använda namngivningskonventionen måste egenskapen kommenteras med[Key]
attributet eller konfigureras som en nyckel iOnModelCreating
metoden förDbContext
.
Ändra modellen och uppdatera databasschemat
Din chef på Contoso Pizza ger dig några nya krav, så du måste ändra dina entitetsmodeller. I följande steg ändrar du modellerna med hjälp av mappningsattribut (kallas ibland dataanteckningar).
I Models\Pizza.cs gör du följande ändringar:
- Lägg till ett
using
direktiv förSystem.ComponentModel.DataAnnotations
. - Lägg till ett
[Required]
attribut föreName
egenskapen för att markera egenskapen efter behov. - Lägg till ett
[MaxLength(100)]
attribut föreName
egenskapen för att ange en maximal stränglängd på 100.
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; } }
- Lägg till ett
I Models\Sauce.cs gör du följande ändringar:
- Lägg till ett
using
direktiv förSystem.ComponentModel.DataAnnotations
. - Lägg till ett
[Required]
attribut föreName
egenskapen för att markera egenskapen efter behov. - Lägg till ett
[MaxLength(100)]
attribut föreName
egenskapen för att ange en maximal stränglängd på 100. - Lägg till en
bool
egenskap med namnetIsVegan
.
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; } }
- Lägg till ett
I Models\Topping.cs gör du följande ändringar:
- Lägg till
using
direktiv förSystem.ComponentModel.DataAnnotations
ochSystem.Text.Json.Serialization
. - Lägg till ett
[Required]
attribut föreName
egenskapen för att markera egenskapen efter behov. - Lägg till ett
[MaxLength(100)]
attribut föreName
egenskapen för att ange en maximal stränglängd på 100. - Lägg till en
decimal
egenskap med namnetCalories
direkt efterName
egenskapen . - Lägg till en
Pizzas
egenskap av typenICollection<Pizza>?
för att skapaPizza
-Topping
en många-till-många-relation. - Lägg till ett
[JsonIgnore]
attribut i egenskapenPizzas
.
Viktigt
De här stegen förhindrar
Topping
att entiteter inkluderarPizzas
egenskapen när webb-API-koden serialiserar svaret på JSON. Utan den här ändringen skulle en serialiserad samling toppings innehålla en samling av varje pizza som använder toppingen. Varje pizza i den samlingen skulle innehålla en samling pålägg, som var och en återigen skulle innehålla en samling pizzor. Den här typen av oändlig loop kallas en cirkelreferens och kan inte serialiseras.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; } }
- Lägg till
Spara alla ändringar och kör
dotnet build
.Kör följande kommando för att skapa en migrering för generering av databastabellerna:
dotnet ef migrations add ModelRevisions --context PizzaContext
En migrering med namnet ModelRevisions skapas.
Anteckning
Det här meddelandet visas: En åtgärd har autogenererats som kan leda till dataförlust. Granska migreringen för korrekthet. Meddelandet visas eftersom du har ändrat relationen från
Pizza
tillTopping
från en-till-många till många-till-många, vilket kräver att en befintlig sekundärnyckelkolumn tas bort. Eftersom du ännu inte har några data i databasen är den här ändringen inte problematisk. I allmänhet är det dock en bra idé att kontrollera den genererade migreringen när den här varningen verkar se till att inga data tas bort eller trunkeras av migreringen.Tillämpa ModelRevisions-migreringen genom att köra följande kommando:
dotnet ef database update --context PizzaContext
I namnlisten i mappen SQLite Explorer väljer du knappen Uppdatera databaser .
Högerklicka på ContosoPizza.db i mappen SQLite Explorer. Välj Visa tabell "sqlite_master" för att visa det fullständiga databasschemat och begränsningarna.
Viktigt
SQLite-tillägget återanvänder öppna SQLite-flikar .
- En
PizzaTopping
kopplingstabell skapades för att representera många-till-många-relationen mellan pizzor och pålägg. - Nya fält har lagts till
Toppings
i ochSauces
.Calories
definieras som entext
kolumn eftersom SQLite inte har någon matchandedecimal
typ.IsVegan
På samma sätt definieras som eninteger
kolumn. SQLite definierarbool
ingen typ.- I båda fallen hanterar EF Core översättningen.
- Kolumnen
Name
i varje tabell har markeratsnot null
, men SQLite harMaxLength
ingen begränsning.
Tips
EF Core-databasprovidrar mappar ett modellschema till funktionerna i en specifik databas. Även om SQLite inte implementerar någon motsvarande begränsning för
MaxLength
, gör andra databaser som SQL Server och PostgreSQL.- En
Högerklicka på
_EFMigrationsHistory
tabellen i mappen SQLite Explorer och välj Visa tabell. Tabellen innehåller en lista över alla migreringar som tillämpas på databasen. Eftersom du har kört två migreringar finns det två poster: en för migreringen InitialCreate och en annan för ModelRevisions.
Anteckning
I den här övningen användes mappningsattribut (dataanteckningar) för att mappa modeller till databasen. Som ett alternativ till mappningsattribut kan du använda Api:et ModelBuilder fluent för att konfigurera modeller. Båda metoderna är giltiga, men vissa utvecklare föredrar en metod framför den andra.
Du har använt migreringar för att definiera och uppdatera ett databasschema. I nästa lektion slutför du metoderna i PizzaService
dessa manipulerade data.