Oefening: een migratie instellen

Voltooid

In deze eenheid maakt u C#-entiteitsklassen die worden toegewezen aan tabellen in een lokale SQLite-database. De functie EF Core-migraties produceert tabellen van deze entiteiten.

Een migratie biedt een manier om het databaseschema incrementeel bij te werken.

De projectbestanden ophalen

Om aan de slag te gaan, haalt u de projectbestanden op. U hebt een aantal opties voor het ophalen van de projectbestanden:

  • GitHub Codespaces gebruiken
  • De GitHub-opslagplaats klonen

Als u een compatibele containerruntime hebt geïnstalleerd, kunt u ook de extensie Dev Containers gebruiken om de opslagplaats te openen in een container waarop de hulpprogramma's vooraf zijn geïnstalleerd.

GitHub Codespaces gebruiken

Een codespace is een IDE die wordt gehost in de cloud. Als u GitHub Codespaces gebruikt, gaat u naar de opslagplaats in uw browser. Selecteer Code en maak vervolgens een nieuwe coderuimte in de main vertakking.

De GitHub-opslagplaats klonen

Als u GitHub Codespaces niet gebruikt, kunt u de GitHub-opslagplaats van het project klonen en vervolgens de bestanden openen als een map in Visual Studio Code.

  1. Open een opdrachtterminal en kloon het project vervolgens vanuit GitHub met behulp van de opdrachtprompt:

    git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
    
  2. Ga naar de map mslearn-persist-data-ef-core en open het project in Visual Studio Code:

    cd mslearn-persist-data-ef-core
    code .
    

De code bekijken

Nu u de projectbestanden hebt om mee te werken, gaan we eens kijken wat er in het project staat en de code bekijken.

  • Het ASP.NET Core-web-API-project bevindt zich in de map ContosoPizza . De bestandspaden waarnaar in deze module wordt verwezen, zijn relatief ten opzichte van de map ContosoPizza .
  • Services/PizzaService.cs is een serviceklasse waarmee CRUD-methoden (Create, Read, Update en Delete) worden gedefinieerd. Alle methoden die momenteel worden gegooid System.NotImplementedException.
  • In Program.csPizzaService wordt geregistreerd bij het ASP.NET Core-afhankelijkheidsinjectiesysteem.
  • Controllers/PizzaController.cs is een waarde voor ApiController het beschikbaar maken van een eindpunt voor HTTP POST-, GET-, PUT- en DELETE-werkwoorden. Met deze werkwoorden worden de bijbehorende CRUD-methoden aangeroepen.PizzaService PizzaService wordt in de PizzaController constructor geïnjecteerd.
  • De map Modellen bevat de modellen die PizzaService en PizzaController deze gebruiken.
  • De entiteitsmodellen, Pizza.cs, Topping.cs en Sauce.cs, hebben de volgende relaties:
    • Een pizza kan een of meer toppings hebben.
    • Een topping kan op een of meerdere pizza's worden gebruikt.
    • Een pizza kan één saus hebben, maar een saus kan op veel pizza's worden gebruikt.

De app bouwen

De app bouwen in Visual Studio Code:

  1. Klik in het deelvenster Explorer met de rechtermuisknop op de map ContosoPizza en selecteer Openen in geïntegreerde terminal.

    Er wordt een terminalvenster geopend dat is gericht op de map ContosoPizza .

  2. Bouw de app met behulp van de volgende opdracht:

    dotnet build
    

    De code moet worden gebouwd zonder waarschuwingen of fouten.

NuGet-pakketten en EF Core-hulpprogramma's toevoegen

De database-engine waarmee u in deze module werkt, is SQLite. SQLite is een lichtgewicht database-engine op basis van bestanden. Het is een goede keuze voor ontwikkeling en testen en het is ook een goede keuze voor kleinschalige productie-implementaties.

Notitie

Zoals eerder vermeld, zijn databaseproviders in EF Core pluggable. SQLite is een goede keuze voor deze module omdat deze lichtgewicht en platformoverschrijdend is. U kunt dezelfde code gebruiken om te werken met verschillende database-engines, zoals SQL Server en PostgreSQL. U kunt zelfs meerdere database-engines in dezelfde app gebruiken.

Voordat u begint, voegt u de vereiste pakketten toe:

  1. Voer in het terminalvenster de volgende opdracht uit:

    dotnet add package Microsoft.EntityFrameworkCore.Sqlite
    

    Met deze opdracht wordt het NuGet-pakket toegevoegd dat de EF Core SQLite-databaseprovider en alle bijbehorende afhankelijkheden bevat, inclusief de algemene EF Core-services.

  2. Voer vervolgens deze opdracht uit:

    dotnet add package Microsoft.EntityFrameworkCore.Design
    

    Met deze opdracht worden pakketten toegevoegd die vereist zijn voor de EF Core-hulpprogramma's.

  3. Voer deze opdracht uit om te voltooien:

    dotnet tool install --global dotnet-ef
    

    Met deze opdracht wordt het hulpprogramma geïnstalleerd dotnet efdat u gebruikt om migraties en scaffolding te maken.

    Tip

    Als dotnet ef deze al is geïnstalleerd, kunt u deze bijwerken door deze uit te voeren dotnet tool update --global dotnet-ef.

Scaffold-modellen en DbContext

Nu voegt u een DbContext implementatie toe en configureert u deze. DbContext is een gateway waarmee u kunt communiceren met de database.

  1. Klik met de rechtermuisknop op de map ContosoPizza en voeg een nieuwe map toe met de naam Data.

  2. Maak in de map Gegevens een nieuw bestand met de naam PizzaContext.cs. Voeg de volgende code toe aan het lege bestand:

    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>();
    }
    

    In de voorgaande code:

    • De constructor accepteert een parameter van het type DbContextOptions<PizzaContext>. Met de constructor kan externe code de configuratie doorgeven, zodat hetzelfde DbContext kan worden gedeeld tussen test- en productiecode en zelfs kan worden gebruikt met verschillende providers.
    • De DbSet<T> eigenschappen komen overeen met tabellen die in de database moeten worden gemaakt.
    • De tabelnamen komen overeen met de DbSet<T> eigenschapsnamen in de PizzaContext klasse. U kunt dit gedrag indien nodig overschrijven.
    • Wanneer er een instantie wordt gemaakt, PizzaContext worden de , Pizzasen Toppings eigenschappen Saucesweergegeven. Wijzigingen die u aanbrengt in de verzamelingen die deze eigenschappen beschikbaar maken, worden doorgegeven aan de database.
  3. Vervang in Program.cs door // Add the PizzaContext de volgende code:

    builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");
    

    Met de voorgaande code wordt:

    • Registreert bij PizzaContext het ASP.NET Core-afhankelijkheidsinjectiesysteem.
    • Hiermee geeft u op dat PizzaContext de SQLite-databaseprovider wordt gebruikt.
    • Definieert een SQLite-verbindingsreeks die verwijst naar een lokaal bestand, ContosoPizza.db.

    Notitie

    SQLite maakt gebruik van lokale databasebestanden, dus het is geen probleem om de verbindingsreeks te codeeren. Voor netwerkdatabases zoals PostgreSQL en SQL Server moet u altijd uw verbindingsreeks veilig opslaan. Gebruik Secret Manager voor lokale ontwikkeling. Voor productie-implementaties kunt u overwegen om een service zoals Azure Key Vault te gebruiken.

  4. Vervang ook in Program.cs door // Additional using declarations de volgende code.

    using ContosoPizza.Data;
    

    Met deze code worden afhankelijkheden in de vorige stap omgezet.

  5. Sla al uw wijzigingen op. In GitHub Codespaces worden uw wijzigingen automatisch opgeslagen.

  6. Bouw de app in de terminal door uit te voeren dotnet build. De build moet slagen zonder waarschuwingen of fouten.

Een migratie maken en uitvoeren

Maak vervolgens een migratie die u kunt gebruiken om uw eerste database te maken.

  1. Voer in de terminal die is gericht op de projectmap ContosoPizza de volgende opdracht uit om een migratie te genereren voor het maken van de databasetabellen:

    dotnet ef migrations add InitialCreate --context PizzaContext
    

    In de voorgaande opdracht:

    • De migratie heeft de naam: InitialCreate.
    • De optie --context geeft de naam op van de klasse in het project ContosoPizza, welke is afgeleid van DbContext.

    De nieuwe map Migrations wordt weergegeven in de hoofdmap van het project ContosoPizza. De map bevat een <timestamp>_InitialCreate.cs bestand waarin de databasewijzigingen worden beschreven die moeten worden vertaald naar een DDL-wijzigingsscript (Data Definition Language).

  2. Voer de volgende opdracht uit om de migratie InitialCreate toe te passen:

    dotnet ef database update --context PizzaContext
    

    Met deze opdracht wordt de migratie toegepast. ContosoPizza.db bestaat niet, dus met deze opdracht maakt u de migratie in de projectmap.

    Tip

    Alle platforms ondersteunen het dotnet ef hulpprogramma. In Visual Studio in Windows kunt u de Add-Migration en PowerShell-cmdlets gebruiken in het geïntegreerde Update-Database.

De database controleren

EF Core heeft een database voor uw app gemaakt. Laten we nu eens kijken in de database met behulp van de SQLite-extensie.

  1. Klik in het deelvenster Explorer met de rechtermuisknop op het bestand ContosoPizza.db en selecteer Database openen.

    Schermopname van de menuoptie Database openen in het deelvenster Visual Studio Code Explorer.

    Er wordt een SQLite Explorer-map weergegeven in het deelvenster Explorer .

    Schermopname van de map SQLite Explorer in het deelvenster Explorer.

  2. Selecteer de map SQLite Explorer om het knooppunt en alle onderliggende knooppunten uit te vouwen. Klik met de rechtermuisknop op ContosoPizza.db en selecteer Tabel weergeven sqlite_master om het volledige databaseschema en de beperkingen weer te geven die door de migratie zijn gemaakt.

    Schermopname van de uitgevouwen MAP SQLite Explorer in het deelvenster Explorer.

    • Tabellen die overeenkomen met elke entiteit zijn gemaakt.
    • Tabelnamen zijn genomen uit de namen van de DbSet eigenschappen op de PizzaContext.
    • Eigenschappen met de naam Id zijn afgeleid dat het automatisch genereren van primaire-sleutelvelden is.
    • De naamconventies voor de primaire sleutel van EF Core en refererende sleutels zijn PK_<primary key property> respectievelijk FK_<dependent entity>_<principal entity>_<foreign key property>. De tijdelijke aanduidingen <dependent entity> en <principal entity> komen overeen met de namen van de entiteitsklassen.

    Notitie

    Net als ASP.NET Core MVC gebruikt EF Core een conventie voor de configuratiebenadering . EF Core-conventies korten de ontwikkelingstijd in door de intentie van de ontwikkelaar af te leiden. Ef Core bepaalt bijvoorbeeld een eigenschap met de naam Id of <entity name>Id de primaire sleutel van de gegenereerde tabel. Als u ervoor kiest om de naamconventie niet te gebruiken, moet u aantekeningen toevoegen aan de eigenschap met het [Key] kenmerk of deze configureren als een sleutel in de OnModelCreating methode van de DbContext.

Het model wijzigen en het databaseschema bijwerken

Uw manager bij Contoso Pizza biedt u enkele nieuwe vereisten, dus u moet uw entiteitsmodellen wijzigen. In de volgende stappen wijzigt u de modellen met behulp van toewijzingskenmerken (ook wel gegevensaantekeningen genoemd).

  1. Breng in Modellen\Pizza.cs de volgende wijzigingen aan:

    1. Voeg een using richtlijn toe voor System.ComponentModel.DataAnnotations.
    2. Voeg een [Required] kenmerk toe vóór de Name eigenschap om de eigenschap zo nodig te markeren.
    3. Voeg een [MaxLength(100)] kenmerk toe vóór de Name eigenschap om een maximale tekenreekslengte van 100 op te geven.

    Het bijgewerkte Pizza.cs-bestand moet eruitzien als de volgende code:

    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; }
    }
    
  2. Breng in Modellen\Sauce.cs de volgende wijzigingen aan:

    1. Voeg een using richtlijn toe voor System.ComponentModel.DataAnnotations.
    2. Voeg een [Required] kenmerk toe vóór de Name eigenschap om de eigenschap zo nodig te markeren.
    3. Voeg een [MaxLength(100)] kenmerk toe vóór de Name eigenschap om een maximale tekenreekslengte van 100 op te geven.
    4. Voeg een bool eigenschap toe met de naam IsVegan.

    Het bijgewerkte Sauce.cs-bestand moet eruitzien als de volgende code:

    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; }
    }
    
  3. Breng in Modellen\Topping.cs de volgende wijzigingen aan:

    1. Voeg using richtlijnen toe voor System.ComponentModel.DataAnnotations en System.Text.Json.Serialization.

    2. Voeg een [Required] kenmerk toe vóór de Name eigenschap om de eigenschap zo nodig te markeren.

    3. Voeg een [MaxLength(100)] kenmerk toe vóór de Name eigenschap om een maximale tekenreekslengte van 100 op te geven.

    4. Voeg direct na de eigenschap een decimal eigenschap toe met de Calories naamName.

    5. Voeg een Pizzas eigenschap van het type ICollection<Pizza>?toe. Deze wijziging maakt Pizza-Topping een veel-op-veel-relatie.

    6. Voeg een [JsonIgnore] kenmerk toe aan de Pizzas eigenschap.

      Belangrijk

      Dit kenmerk voorkomt dat Topping entiteiten de Pizzas eigenschap opnemen wanneer de web-API-code het antwoord naar JSON serialiseert. Zonder deze wijziging bevat een geserialiseerde verzameling toppings een verzameling van elke pizza die gebruikmaakt van de topping. Elke pizza in die verzameling zou een verzameling toppings bevatten, die elk weer een verzameling pizza's zou bevatten. Dit type oneindige lus wordt een kringverwijzing genoemd en kan niet worden geserialiseerd.

    Het bijgewerkte Topping.cs-bestand moet eruitzien als de volgende code:

    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; }
    }
    
  4. Sla al uw wijzigingen op en voer deze uit dotnet build.

  5. Voer de volgende opdracht uit om een migratie te genereren voor het maken van databasetabellen:

    dotnet ef migrations add ModelRevisions --context PizzaContext
    

    Met deze opdracht maakt u een migratie met de naam: ModelRevisions.

    Notitie

    U ziet dit bericht: Er is een bewerking uitgevoerd die kan leiden tot het verlies van gegevens. Controleer de migratie op nauwkeurigheid. Dit bericht werd weergegeven omdat u de relatie hebt gewijzigd van Pizza van Topping een-op-veel naar veel-op-veel, waarvoor een bestaande refererende-sleutelkolom moet worden verwijderd. Omdat u nog geen gegevens in uw database hebt, is deze wijziging geen probleem. Over het algemeen is het echter een goed idee om de gegenereerde migratie te controleren wanneer deze waarschuwing wordt weergegeven om ervoor te zorgen dat de migratie geen gegevens verwijdert of afkappen.

  6. Voer de volgende opdracht uit om de migratie ModelRevisions toe te passen:

    dotnet ef database update --context PizzaContext
    
  7. Selecteer op de titelbalk van de map SQLite Explorer de knop Databases vernieuwen.

    Schermopname van de knop Databases vernieuwen op de titelbalk van SQLite Explorer.

  8. Klik in de map SQLite Explorer met de rechtermuisknop op ContosoPizza.db. Selecteer Tabel 'sqlite_master' weergeven om het volledige databaseschema en de beperkingen weer te geven.

    Belangrijk

    De SQLite-extensie hergebruikt geopende SQLite-tabbladen .

    • Er is een PizzaTopping jointabel gemaakt om de veel-op-veel-relatie tussen pizza's en toppings weer te geven.
    • Er zijn nieuwe velden toegevoegd aan Toppings en Sauces.
      • Calories is gedefinieerd als een text kolom omdat SQLite geen overeenkomend decimal type heeft.
      • Op dezelfde manier IsVegan wordt gedefinieerd als een integer kolom. SQLite definieert bool geen type.
      • In beide gevallen beheert EF Core de vertaling.
    • De Name kolom in elke tabel is gemarkeerd not null, maar SQLite heeft MaxLength geen beperking.

    Tip

    EF Core-databaseproviders wijzen een modelschema toe aan de functies van een specifieke database. Hoewel SQLite geen overeenkomstige beperking implementeert voor MaxLengthandere databases zoals SQL Server en PostgreSQL.

  9. Klik in de map SQLite Explorer met de rechtermuisknop op de _EFMigrationsHistory tabel en selecteer Tabel weergeven. De tabel bevat een lijst met alle migraties die worden toegepast op de database. Omdat u twee migraties hebt uitgevoerd, zijn er twee vermeldingen: een voor de InitialCreate-migratie en een andere voor ModelRevisions.

Notitie

In deze oefening worden toewijzingskenmerken (gegevensaantekeningen) gebruikt om modellen toe te wijzen aan de database. Als alternatief voor het toewijzen van kenmerken kunt u de Fluent API van ModelBuilder gebruiken om modellen te configureren. Beide benaderingen zijn geldig, maar sommige ontwikkelaars geven de voorkeur aan één benadering ten opzichte van de andere.

U hebt migraties gebruikt om een databaseschema te definiëren en bij te werken. In de volgende les voltooit u de methoden in PizzaService die gegevens bewerken.

Kennis testen

1.

Wat is in een entiteitsklasse de naamconventie voor eigenschappen als primaire sleutel?