Latihan - Menyiapkan migrasi
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.
Buka terminal perintah, lalu klon proyek dari GitHub dengan menggunakan prompt perintah:
git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
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 padaPizzaService
.PizzaService
disuntikkan kePizzaController
konstruktor. - Folder Model berisi model yang digunakan oleh
PizzaService
danPizzaController
. - 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:
Pada panel Explorer , klik kanan direktori ContosoPizza dan pilih Buka di Terminal Terintegrasi.
Panel terminal yang terlingkup ke direktori ContosoPizza terbuka.
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:
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.
Jalankan perintah ini:
dotnet add package Microsoft.EntityFrameworkCore.Design
Perintah ini menambahkan paket yang diperlukan untuk alat EF Core.
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 menjalankandotnet 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.
Klik kanan direktori ContosoPizza dan tambahkan folder baru yang disebut Data.
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 samaDbContext
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 kelasPizzaContext
. Anda dapat mengambil alih perilaku ini jika diperlukan. - Ketika dibuat instansnya,
PizzaContext
akan mengekspos propertiPizzas
,Toppings
, danSauces
. Perubahan yang Anda buat pada koleksi yang diekspos oleh properti tersebut akan disebarluaskan ke database.
- Konstruktor menerima parameter dari jenis
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.
Selain itu di Program.cs, ganti
// Additional using declarations
dengan kode berikut.using ContosoPizza.Data;
Kode ini menyelesaikan dependensi pada langkah sebelumnya.
Simpan semua perubahan yang Anda lakukan. GitHub Codespaces menyimpan perubahan Anda secara otomatis.
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.
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 dariDbContext
.
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).
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 menggunakanAdd-Migration
cmdlet PowerShell danUpdate-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.
Pada panel Explorer , klik kanan file ContosoPizza.db dan pilih Buka Database.
Folder SQLite Explorer muncul di panel Explorer .
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.
- Tabel yang sesuai dengan setiap entitas dibuat.
- Nama tabel diambil dari nama properti
DbSet
padaPizzaContext
. - 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>
danFK_<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 metodeOnModelCreating
dariDbContext
.
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).
Di Models\Pizza.cs, buat perubahan berikut:
- Tambahkan direktif
using
untukSystem.ComponentModel.DataAnnotations
. - Tambahkan atribut
[Required]
sebelum propertiName
untuk menandai properti sebagai diperlukan. - Tambahkan atribut
[MaxLength(100)]
sebelum propertiName
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; } }
- Tambahkan direktif
Di Models\Sauce.cs, buat perubahan berikut:
- Tambahkan direktif
using
untukSystem.ComponentModel.DataAnnotations
. - Tambahkan atribut
[Required]
sebelum propertiName
untuk menandai properti sebagai diperlukan. - Tambahkan atribut
[MaxLength(100)]
sebelum propertiName
untuk menentukan panjang string maksimum 100. - Tambahkan properti
bool
bernamaIsVegan
.
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; } }
- Tambahkan direktif
Di Models\Topping.cs, buat perubahan berikut:
- Tambahkan direktif
using
untukSystem.ComponentModel.DataAnnotations
danSystem.Text.Json.Serialization
. - Tambahkan atribut
[Required]
sebelum propertiName
untuk menandai properti sebagai diperlukan. - Tambahkan atribut
[MaxLength(100)]
sebelum propertiName
untuk menentukan panjang string maksimum 100. - Tambahkan properti
decimal
bernamaCalories
tepat setelah propertiName
. - Tambahkan properti
Pizzas
jenisICollection<Pizza>?
untuk membuatPizza
-Topping
hubungan banyak ke banyak. - Tambahkan atribut
[JsonIgnore]
ke propertiPizzas
.
Penting
Langkah-langkah ini mencegah
Topping
entitas menyertakanPizzas
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; } }
- Tambahkan direktif
Simpan semua perubahan Anda dan jalankan
dotnet build
.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
dariPizza
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.Jalankan perintah berikut untuk menerapkan migrasi ModelRevisions:
dotnet ef database update --context PizzaContext
Pada bilah judul folder SQLite Explorer , pilih tombol Refresh Database .
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
danSauces
.Calories
didefinisikan sebagai kolomtext
karena SQLite tidak memiliki jenisdecimal
yang cocok.- Begitu juga,
IsVegan
didefinisikan sebagai kolominteger
. SQLite tidak mendefinisikan jenisbool
. - Dalam kedua kasus tersebut, EF Core mengelola penerjemahan.
- Kolom
Name
di setiap tabel telah ditandainot null
, tetapi SQLite tidak memiliki batasanMaxLength
.
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.- Tabel gabungan
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.