Latihan - Menyiapkan migrasi

Selesai

Dalam unit ini, Anda membuat kelas entitas C# yang akan memetakan ke tabel dalam database SQLite lokal. Fitur migrasi EF Core menghasilkan tabel dari entitas tersebut.

Migrasi menyediakan cara untuk memperbarui skema database secara bertahap.

Mendapatkan file proyek

Untuk memulai, dapatkan file proyek. Anda memiliki beberapa opsi untuk bagaimana Anda mendapatkan file proyek:

  • Menggunakan GitHub Codespaces
  • Mengklon repositori GitHub

Jika Anda memiliki runtime kontainer yang kompatibel yang terinstal, Anda juga dapat menggunakan ekstensi Dev Containers untuk membuka repositori dalam kontainer dengan alat yang telah diinstal sebelumnya.

Menggunakan GitHub Codespaces

Codespace adalah IDE yang dihosting di cloud. Jika Anda menggunakan GitHub Codespaces, buka repositori di browser Anda. Pilih Kode, lalu buat ruang kode baru di main cabang.

Mengklon repositori GitHub

Jika Anda tidak menggunakan GitHub Codespaces, Anda dapat mengkloning repositori GitHub proyek, lalu membuka file sebagai folder di Visual Studio Code.

  1. Buka terminal perintah, lalu klon proyek dari GitHub dengan menggunakan prompt perintah:

    git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
    
  2. Buka folder mslearn-persist-data-ef-core, lalu buka proyek di Visual Studio Code:

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

Mengulas kode

Sekarang Anda memiliki file proyek untuk dikerjakan. Lihat apa yang ada dalam proyek, dan tinjau kodenya.

  • Proyek ini, api web ASP.NET Core, terletak di direktori ContosoPizza . Jalur file yang dimaksud dalam modul ini relatif terhadap direktori ContosoPizza .
  • Services/PizzaService.cs adalah kelas layanan yang mendefinisikan metode buat, baca, perbarui, dan hapus (CRUD). Semua metode saat ini menampilkan System.NotImplementedException.
  • Di Program.cs, PizzaService terdaftar dengan sistem injeksi dependensi ASP.NET Core.
  • Controllers/PizzaController.cs adalah nilai untuk ApiController yang mengekspos titik akhir untuk kata kerja HTTP POST, GET, PUT, dan DELETE. Kata kerja ini memanggil metode CRUD yang sesuai pada PizzaService. PizzaService disuntikkan ke PizzaController konstruktor.
  • Folder Model berisi model yang digunakan oleh PizzaService dan PizzaController.
  • Model entitas, Pizza.cs, Topping.cs, dan Sauce.cs, memiliki hubungan berikut:
    • Pizza dapat memiliki satu atau beberapa topping.
    • Topping dapat digunakan pada satu atau di banyak pizza.
    • Pizza dapat memiliki satu saringan, tetapi saringan dapat digunakan di banyak pizza.

Membangun aplikasi

Untuk membuat aplikasi di Visual Studio Code:

  1. Pada panel Explorer , klik kanan direktori ContosoPizza dan pilih Buka di Terminal Terintegrasi.

    Panel terminal yang terlingkup ke direktori ContosoPizza terbuka.

  2. Buat aplikasi dengan menggunakan perintah berikut:

    dotnet build
    

    Kode harus dibuat tanpa ada peringatan atau kesalahan.

Tambahkan paket NuGet dan alat EF Core

Mesin database yang bekerja dengan Anda dalam modul ini adalah SQLite. SQLite adalah mesin database berbasis file yang ringan. Ini adalah pilihan yang baik untuk pengembangan dan pengujian, dan ini juga merupakan pilihan yang baik untuk penyebaran produksi skala kecil.

Catatan

Seperti disebutkan sebelumnya, penyedia database di EF Core dapat dicolokkan. SQLite adalah pilihan yang baik untuk modul ini karena ringan dan lintas platform. Anda dapat menggunakan kode yang sama untuk bekerja dengan mesin database yang berbeda, seperti SQL Server dan PostgreSQL. Anda bahkan dapat menggunakan beberapa mesin database di aplikasi yang sama.

Sebelum memulai, tambahkan paket yang diperlukan:

  1. Pada panel terminal, jalankan perintah berikut ini:

    dotnet add package Microsoft.EntityFrameworkCore.Sqlite
    

    Perintah ini menambahkan paket NuGet yang berisi penyedia database EF Core SQLite dan memanggil dependensinya, termasuk layanan EF Core umum.

  2. Jalankan perintah ini:

    dotnet add package Microsoft.EntityFrameworkCore.Design
    

    Perintah ini menambahkan paket yang diperlukan untuk alat EF Core.

  3. Untuk menyelesaikannya, jalankan perintah ini:

    dotnet tool install --global dotnet-ef
    

    Perintah ini menginstal dotnet ef, alat yang akan Anda gunakan untuk membuat migrasi dan perancah.

    Tip

    Jika dotnet ef sudah diinstal, Anda dapat memperbaruinya dengan menjalankan dotnet tool update --global dotnet-ef.

Model perancah dan DbContext

Sekarang Anda menambahkan dan mengonfigurasi DbContext implementasi. DbContext adalah gateway tempat Anda dapat berinteraksi dengan database.

  1. Klik kanan direktori ContosoPizza dan tambahkan folder baru yang disebut Data.

  2. Di folder Data , buat file baru bernama PizzaContext.cs. Tambahkan kode berikut ke file kosong:

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

    Dalam kode sebelumnya:

    • Konstruktor menerima parameter dari jenis DbContextOptions<PizzaContext>. Konstruktor memungkinkan kode eksternal untuk meneruskan konfigurasi sehingga hal yang sama DbContext dapat dibagikan antara kode pengujian dan produksi, dan bahkan digunakan dengan penyedia yang berbeda.
    • Properti DbSet<T> sesuai dengan tabel yang akan dibuat dalam database.
    • Nama tabel akan sesuai dengan nama properti DbSet<T> dalam kelas PizzaContext. Anda dapat mengambil alih perilaku ini jika diperlukan.
    • Ketika dibuat instansnya, PizzaContext akan mengekspos properti Pizzas, Toppings, dan Sauces. Perubahan yang Anda buat pada koleksi yang diekspos oleh properti tersebut akan disebarluaskan ke database.
  3. Di Program.cs, ganti // Add the PizzaContext dengan kode berikut:

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

    Kode sebelumnya:

    • PizzaContext Mendaftar dengan sistem injeksi dependensi ASP.NET Core.
    • Menentukan bahwa PizzaContext akan menggunakan penyedia database SQLite.
    • Mendefinisikan string koneksi SQLite yang mengarah ke file lokal, ContosoPizza.db.

    Catatan

    SQLite menggunakan file database lokal, jadi mungkin tidak apa-apa untuk mengodekan string koneksi secara permanen. Untuk database jaringan seperti PostgreSQL dan SQL Server, Anda harus selalu menyimpan string koneksi Anda dengan aman. Untuk pengembangan lokal, gunakan Secret Manager. Untuk penyebaran produksi, pertimbangkan untuk menggunakan layanan seperti Azure Key Vault.

  4. Selain itu di Program.cs, ganti // Additional using declarations dengan kode berikut.

    using ContosoPizza.Data;
    

    Kode ini menyelesaikan dependensi pada langkah sebelumnya.

  5. Simpan semua perubahan yang Anda lakukan. GitHub Codespaces menyimpan perubahan Anda secara otomatis.

  6. Buat aplikasi di terminal dengan menjalankan dotnet build. Build akan berhasil tanpa peringatan atau kesalahan.

Buat dan jalankan migrasi

Selanjutnya, buat migrasi yang bisa Anda gunakan untuk membuat database awal Anda.

  1. Jalankan perintah berikut untuk membuat migrasi pembuatan tabel database:

    dotnet ef migrations add InitialCreate --context PizzaContext
    

    Dalam perintah sebelumnya:

    • Migrasi diberi nama InitialCreate.
    • Opsi --context menentukan nama kelas dalam proyek ContosoPizza, yang berasal dari DbContext.

    Direktori Migrations baru muncul di akar proyek ContosoPizza. Direktori berisi <timestamp>_InitialCreate.cs file yang menjelaskan perubahan database yang akan diterjemahkan ke skrip perubahan Bahasa Definisi Data (DDL).

  2. Jalankan perintah berikut untuk menerapkan migrasi InitialCreate:

    dotnet ef database update --context PizzaContext
    

    Perintah ini menerapkan migrasi. ContosoPizza.db tidak ada, sehingga migrasi dibuat di direktori proyek.

    Tip

    Alat dotnet ef didukung di semua platform. Di Visual Studio di Windows, Anda dapat menggunakan Add-Migration cmdlet PowerShell dan Update-Database di jendela Konsol Manajer Paket terintegrasi.

Memeriksa database

EF Core membuat database untuk aplikasi Anda. Selanjutnya, lihat di dalam database dengan menggunakan ekstensi SQLite.

  1. Pada panel Explorer , klik kanan file ContosoPizza.db dan pilih Buka Database.

    Cuplikan layar yang memperlihatkan opsi menu Buka Database di panel Visual Studio Code Explorer.

    Folder SQLite Explorer muncul di panel Explorer .

    Cuplikan layar yang memperlihatkan folder SQLite Explorer di panel Explorer.

  2. Pilih folder SQLite Explorer untuk memperluas simpul dan semua simpul anaknya. Klik kanan ContosoPizza.db dan pilih Tampilkan Tabel 'sqlite_master' untuk melihat skema dan batasan database lengkap yang dibuat migrasi.

    Cuplikan layar yang memperlihatkan folder SQLite Explorer yang diperluas di panel Explorer.

    • Tabel yang sesuai dengan setiap entitas dibuat.
    • Nama tabel diambil dari nama properti DbSet pada PizzaContext.
    • Properti bernama Id disimpulkan sebagai bidang kunci primer yang ditambahkan secara otomatis.
    • Kunci primer EF Core dan konvensi penamaan batasan kunci asing masing-masing adalah PK_<primary key property> dan FK_<dependent entity>_<principal entity>_<foreign key property>. Tempat penampung <dependent entity> dan <principal entity> sesuai dengan nama kelas entitas.

    Catatan

    Seperti ASP.NET Core MVC, EF Core menggunakan konvensi atas pendekatan konfigurasi . Konvensi EF Core mempersingkat waktu pengembangan dengan menyimpulkan niat pengembang. Misalnya, properti bernama Id atau <entity name>Id disimpulkan sebagai kunci primer tabel yang dibuat. Jika Anda memilih untuk tidak mengadopsi konvensi penamaan, properti harus diannotasikan dengan atribut [Key] atau dikonfigurasi sebagai kunci dalam metode OnModelCreating dari DbContext.

Mengubah model dan memperbarui skema database

Manajer Anda di Contoso Pizza memberi Anda beberapa persyaratan baru, jadi Anda harus mengubah model entitas Anda. Dalam langkah-langkah berikut, Anda memodifikasi model dengan menggunakan atribut pemetaan (terkadang disebut anotasi data).

  1. Di Models\Pizza.cs, buat perubahan berikut:

    1. Tambahkan direktif using untuk System.ComponentModel.DataAnnotations.
    2. Tambahkan atribut [Required] sebelum properti Name untuk menandai properti sebagai diperlukan.
    3. Tambahkan atribut [MaxLength(100)] sebelum properti Name untuk menentukan panjang string maksimum 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; }
    }
    
  2. Di Models\Sauce.cs, buat perubahan berikut:

    1. Tambahkan direktif using untuk System.ComponentModel.DataAnnotations.
    2. Tambahkan atribut [Required] sebelum properti Name untuk menandai properti sebagai diperlukan.
    3. Tambahkan atribut [MaxLength(100)] sebelum properti Name untuk menentukan panjang string maksimum 100.
    4. Tambahkan properti bool bernama IsVegan.
    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. Di Models\Topping.cs, buat perubahan berikut:

    1. Tambahkan direktif using untuk System.ComponentModel.DataAnnotations dan System.Text.Json.Serialization.
    2. Tambahkan atribut [Required] sebelum properti Name untuk menandai properti sebagai diperlukan.
    3. Tambahkan atribut [MaxLength(100)] sebelum properti Name untuk menentukan panjang string maksimum 100.
    4. Tambahkan properti decimal bernama Calories tepat setelah properti Name.
    5. Tambahkan properti Pizzas jenis ICollection<Pizza>? untuk membuat Pizza-Topping hubungan banyak ke banyak.
    6. Tambahkan atribut [JsonIgnore] ke properti Pizzas.

    Penting

    Langkah-langkah ini mencegah Topping entitas menyertakan Pizzas properti saat kode API web menserialisasikan respons terhadap JSON. Tanpa perubahan ini, koleksi topping berseri akan mencakup koleksi setiap pizza yang menggunakan topping. Masing-masing pizza dalam koleksi tersebut akan menyertakan kumpulan topping, yang masing-masing juga menyertakan kumpulan pizza. Jenis loop tak terbatas ini disebut referensi melingkar dan tidak dapat diserialisasi.

    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. Simpan semua perubahan Anda dan jalankan dotnet build.

  5. Jalankan perintah berikut untuk membuat migrasi pembuatan tabel database:

    dotnet ef migrations add ModelRevisions --context PizzaContext
    

    Migrasi bernama ModelRevisions dibuat.

    Catatan

    Pesan ini muncul: Operasi dibuat perancah yang dapat mengakibatkan hilangnya data. Harap tinjau migrasi untuk akurasi. Pesan muncul karena Anda mengubah hubungan dari ke Topping dari Pizza satu ke banyak menjadi banyak ke banyak, yang mengharuskan kolom kunci asing yang ada dihilangkan. Karena Anda belum memiliki data apa pun di database Anda, perubahan ini tidak bermasalah. Namun, secara umum, ada baiknya untuk memeriksa migrasi yang dihasilkan ketika peringatan ini tampaknya memastikan bahwa tidak ada data yang dihapus atau dipotok oleh migrasi.

  6. Jalankan perintah berikut untuk menerapkan migrasi ModelRevisions:

    dotnet ef database update --context PizzaContext
    
  7. Pada bilah judul folder SQLite Explorer , pilih tombol Refresh Database .

    Cuplikan layar yang memperlihatkan tombol Refresh Database pada bilah judul SQLite Explorer.

  8. Di folder SQLite Explorer , klik kanan ContosoPizza.db. Pilih Tampilkan Tabel 'sqlite_master' untuk melihat semua batasan dan skema database.

    Penting

    Ekstensi SQLite menggunakan kembali tab SQLite yang terbuka.

    • Tabel gabungan PizzaTopping dibuat untuk merepresentasikan hubungan banyak ke banyak antara pizza dan topping.
    • Bidang baru telah ditambahkan ke Toppings dan Sauces.
      • Calories didefinisikan sebagai kolom text karena SQLite tidak memiliki jenis decimal yang cocok.
      • Begitu juga, IsVegan didefinisikan sebagai kolom integer. SQLite tidak mendefinisikan jenis bool.
      • Dalam kedua kasus tersebut, EF Core mengelola penerjemahan.
    • Kolom Name di setiap tabel telah ditandai not null, tetapi SQLite tidak memiliki batasan MaxLength.

    Tip

    Penyedia database EF Core memetakan skema model ke fitur database tertentu. Meskipun SQLite tidak menerapkan batasan yang sesuai untuk MaxLength, database lain seperti SQL Server dan PostgreSQL.

  9. Di folder SQLite Explorer , klik _EFMigrationsHistory kanan tabel dan pilih Perlihatkan Tabel. Tabel berisi daftar semua migrasi yang diterapkan ke database. Karena Anda telah menjalankan dua migrasi, ada dua entri: satu untuk migrasi InitialCreate , dan satu lagi untuk ModelRevisions.

Catatan

Latihan ini menggunakan atribut pemetaan (anotasi data) untuk memetakan model ke database. Sebagai alternatif untuk memetakan atribut, Anda dapat menggunakan API fasih ModelBuilder untuk mengonfigurasi model. Kedua pendekatan tersebut valid, tetapi beberapa pengembang lebih memilih satu pendekatan daripada yang lain.

Anda telah menggunakan migrasi untuk mendefinisikan dan memperbarui skema database. Di unit berikutnya, Anda akan menyelesaikan metode di PizzaService yang memanipulasi data.

Uji pengetahuan Anda

1.

Di kelas entitas, apa konvensi penamaan properti untuk kunci primer?