Razor Halaman dengan Entity Framework Core di ASP.NET Core - Tutorial 1 dari 8
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Oleh Tom Dykstra, Jeremy Likness, dan Jon P Smith
Ini adalah yang pertama dalam serangkaian tutorial yang menunjukkan cara menggunakan Entity Framework (EF) Core di aplikasi ASP.NET Core Razor Pages . Tutorial ini membangun situs web untuk Universitas Contoso fiktif. Situs ini mencakup fungsionalitas seperti penerimaan siswa, pembuatan kursus, dan penugasan instruktur. Tutorial ini menggunakan pendekatan pertama kode. Untuk informasi tentang mengikuti tutorial ini menggunakan pendekatan pertama database, lihat masalah Github ini.
Unduh atau lihat aplikasi yang telah selesai. Unduh instruksi.
Prasyarat
- Jika Anda baru Razor menggunakan Pages, buka seri tutorial Mulai menggunakan Razor Pages sebelum memulai yang ini.
- Visual Studio 2022 dengan beban kerja ASP.NET serta pengembangan web.
- .NET 6.0 SDK
Mesin database
Instruksi Visual Studio menggunakan SQL Server LocalDB, versi SQL Server Express yang hanya berjalan di Windows.
Pemecahan Masalah
Jika Anda mengalami masalah yang tidak dapat Anda atasi, bandingkan kode Anda dengan proyek yang telah selesai. Cara yang baik untuk mendapatkan bantuan adalah dengan memposting pertanyaan ke StackOverflow.com, menggunakan tag ASP.NET Core atau EF Core tag .
Aplikasi sampel
Aplikasi yang dibangun dalam tutorial ini adalah situs web universitas dasar. Pengguna dapat melihat dan memperbarui informasi siswa, kursus, dan instruktur. Berikut adalah beberapa layar yang dibuat dalam tutorial.
Gaya UI situs ini didasarkan pada templat proyek bawaan. Fokus tutorial adalah pada cara menggunakan EF Core dengan ASP.NET Core, bukan cara menyesuaikan UI.
Opsional: Buat unduhan sampel
Langkah ini bersifat opsional. Membangun aplikasi yang telah selesai disarankan saat Anda memiliki masalah yang tidak dapat Anda selesaikan. Jika Anda mengalami masalah yang tidak dapat Anda atasi, bandingkan kode Anda dengan proyek yang telah selesai. Unduh instruksi.
Pilih ContosoUniversity.csproj
untuk membuka proyek.
Bangun proyek.
Di Package Manager Console (PMC) jalankan perintah berikut:
Update-Database
Jalankan proyek untuk menyemai database.
Membuat proyek aplikasi web
Mulai Visual Studio 2022 dan pilih Buat proyek baru.
Dalam dialog Buat proyek baru, pilih ASP.NET Core Web App, lalu pilih Berikutnya.
Dalam dialog Konfigurasikan proyek baru Anda, masukkan
ContosoUniversity
untuk Nama proyek. Penting untuk memberi nama proyek ContosoUniversity, termasuk mencocokkan kapitalisasi, sehingga namespace akan cocok saat Anda menyalin dan menempelkan kode contoh.Pilih Selanjutnya.
Dalam dialog Informasi tambahan, pilih .NET 6.0 (Dukungan jangka panjang) lalu pilih Buat.
Menyiapkan gaya situs
Salin dan tempel kode berikut ke Pages/Shared/_Layout.cshtml
dalam file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/ContosoUniversity.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
File tata letak mengatur header situs, footer, dan menu. Kode sebelumnya membuat perubahan berikut:
- Setiap kemunculan "ContosoUniversity" ke "Contoso University". Ada tiga kejadian.
- Entri Home menu dan Privacy dihapus.
- Entri ditambahkan untuk Tentang, Siswa, Kursus, Instruktur, dan Departemen.
Di Pages/Index.cshtml
, ganti konten file dengan kode berikut:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
@* <a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
*@ </p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
@* <a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
*@ </p>
</div>
</div>
</div>
</div>
Kode sebelumnya menggantikan teks tentang ASP.NET Core dengan teks tentang aplikasi ini.
Jalankan aplikasi untuk memverifikasi bahwa home halaman muncul.
Model data
Bagian berikut membuat model data:
Siswa dapat mendaftar di sejumlah kursus, dan kursus dapat memiliki sejumlah siswa yang terdaftar di dalamnya.
Entitas Siswa
- Buat folder Model di folder proyek.
- Buat
Models/Student.cs
dengan kode berikut:namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Properti ID
menjadi kolom kunci utama tabel database yang sesuai dengan kelas ini. Secara default, EF Core menginterpretasikan properti yang dinamai ID
atau classnameID
sebagai kunci utama. Jadi nama alternatif yang dikenali secara otomatis untuk Student
kunci utama kelas adalah StudentID
. Untuk informasi selengkapnya, lihat EF Core - Kunci.
Properti Enrollments
adalah properti navigasi. Properti navigasi menyimpan entitas lain yang terkait dengan entitas ini. Dalam hal ini, Enrollments
properti Student
entitas memegang semua entitas yang terkait dengan Siswa tersebut Enrollment
. Misalnya, jika baris Siswa dalam database memiliki dua baris Pendaftaran terkait, properti navigasi berisi dua entitas Pendaftaran tersebut Enrollments
.
Dalam database, baris Pendaftaran terkait dengan baris Siswa jika kolomnya StudentID
berisi nilai ID siswa. Misalnya, baris Siswa memiliki ID=1. Baris Pendaftaran terkait akan memiliki StudentID
= 1. StudentID
adalah kunci asing dalam tabel Pendaftaran.
Properti Enrollments
didefinisikan sebagai ICollection<Enrollment>
karena mungkin ada beberapa entitas Pendaftaran terkait. Jenis koleksi lain dapat digunakan, seperti List<Enrollment>
atau HashSet<Enrollment>
. Saat ICollection<Enrollment>
digunakan, EF Core membuat HashSet<Enrollment>
koleksi secara default.
Entitas Pendaftaran
Buat Models/Enrollment.cs
dengan kode berikut:
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
[DisplayFormat(NullDisplayText = "No grade")]
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Properti EnrollmentID
adalah kunci utama; entitas ini menggunakan pola alih-alih ID
dengan sendirinyaclassnameID
. Untuk model data produksi, banyak pengembang memilih satu pola dan menggunakannya secara konsisten. Tutorial ini menggunakan keduanya hanya untuk menggambarkan bahwa keduanya berfungsi. Menggunakan ID
tanpa classname
mempermudah penerapan beberapa jenis perubahan model data.
Properti Grade
adalah enum
. Tanda tanya setelah Grade
deklarasi jenis menunjukkan bahwa Grade
properti dapat diubah ke null. Nilai null berbeda dari nilai nol—null berarti nilai belum diketahui atau belum ditetapkan.
Properti StudentID
adalah kunci asing, dan properti navigasi yang sesuai adalah Student
. Entitas Enrollment
dikaitkan dengan satu Student
entitas, sehingga properti berisi satu Student
entitas.
Properti CourseID
adalah kunci asing, dan properti navigasi yang sesuai adalah Course
. Entitas Enrollment
dikaitkan dengan satu Course
entitas.
EF Core menafsirkan properti sebagai kunci asing jika bernama <navigation property name><primary key property name>
. Misalnya,StudentID
adalah kunci asing untuk Student
properti navigasi, karena Student
kunci utama entitas adalah ID
. Properti kunci asing juga dapat diberi nama <primary key property name>
. Misalnya, CourseID
karena Course
kunci utama entitas adalah CourseID
.
Entitas Kursus
Buat Models/Course.cs
dengan kode berikut:
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Properti Enrollments
adalah properti navigasi. Entitas Course
dapat terkait dengan sejumlah Enrollment
entitas.
Atribut DatabaseGenerated
ini memungkinkan aplikasi menentukan kunci utama daripada membuat database.
Buat aplikasi. Pengkompilasi menghasilkan beberapa peringatan tentang bagaimana null
nilai ditangani. Lihat masalah GitHub ini, Jenis referensi nullable, dan Tutorial: Mengekspresikan niat desain Anda dengan lebih jelas dengan jenis referensi nullable dan non-nullable untuk informasi selengkapnya.
Untuk menghilangkan peringatan dari jenis referensi yang dapat diubah ke null, hapus baris berikut dari ContosoUniversity.csproj
file:
<Nullable>enable</Nullable>
Mesin perancah saat ini tidak mendukung jenis referensi nullable, oleh karena itu model yang digunakan dalam perancah juga tidak dapat.
?
Hapus anotasi jenis referensi nullable dari public string? RequestId { get; set; }
dalam Pages/Error.cshtml.cs
sehingga proyek dibangun tanpa peringatan kompilator.
Halaman Siswa Perancah
Di bagian ini, alat perancah ASP.NET Core digunakan untuk menghasilkan:
- Sebuah EF Core
DbContext
kelas. Konteksnya adalah kelas utama yang mengoordinasikan fungsionalitas Kerangka Kerja Entitas untuk model data tertentu. Ini berasal dari Microsoft.EntityFrameworkCore.DbContext kelas . - Razor halaman yang menangani operasi Buat, Baca, Perbarui, dan Hapus (CRUD) untuk
Student
entitas.
- Buat folder Halaman/Siswa .
- Di Penjelajah Solusi, klik kanan folder Halaman/Siswa dan pilih Tambahkan>Item Perancah Baru.
- Dalam dialog Tambahkan Item Perancah Baru:
- Di tab sebelah kiri, pilih Halaman Umum >Razor terinstal >
- Pilih Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD)>ADD.
- Dalam dialog Tambahkan Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD):
- Di menu drop-down Kelas model, pilih Siswa (ContosoUniversity.Models).
- Di baris Kelas konteks data, pilih + tanda (plus).
- Ubah nama konteks data menjadi berakhiran
SchoolContext
daripadaContosoUniversityContext
. Nama konteks yang diperbarui:ContosoUniversity.Data.SchoolContext
- Pilih Tambahkan untuk menyelesaikan penambahan kelas konteks data.
- Pilih Tambahkan untuk menyelesaikan dialog Tambahkan Razor Halaman .
- Ubah nama konteks data menjadi berakhiran
Paket berikut diinstal secara otomatis:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
Jika langkah sebelumnya gagal, buat proyek dan coba lagi langkah perancah.
Proses perancah:
- Razor Membuat halaman di folder Halaman/Siswa:
Create.cshtml
danCreate.cshtml.cs
Delete.cshtml
danDelete.cshtml.cs
Details.cshtml
danDetails.cshtml.cs
Edit.cshtml
danEdit.cshtml.cs
Index.cshtml
danIndex.cshtml.cs
Data/SchoolContext.cs
Membuat .- Menambahkan konteks ke injeksi dependensi di
Program.cs
. - Menambahkan database string koneksi ke
appsettings.json
.
Database string koneksi
Alat perancah menghasilkan string koneksi dalam appsettings.json
file.
string koneksi menentukan SQL Server LocalDB:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext-0e9;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB adalah versi ringan dari SQL Server Express Database Engine dan ditujukan untuk pengembangan aplikasi, bukan penggunaan produksi. Secara default, LocalDB membuat file .mdf di C:/Users/<user>
direktori.
Memperbarui kelas konteks database
Kelas utama yang mengoordinasikan EF Core fungsionalitas untuk model data tertentu adalah kelas konteks database. Konteks berasal dari Microsoft.EntityFrameworkCore.DbContext. Konteks menentukan entitas mana yang disertakan dalam model data. Dalam proyek ini, kelas diberi nama SchoolContext
.
Perbarui Data/SchoolContext.cs
dengan kode berikut:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Kode sebelumnya berubah dari tunggal DbSet<Student> Student
ke jamak DbSet<Student> Students
. Untuk membuat Razor kode Pages cocok dengan nama baru DBSet
, buat perubahan global dari: _context.Student.
ke: _context.Students.
Ada 8 kejadian.
Karena kumpulan entitas berisi beberapa entitas, banyak pengembang lebih suka DBSet
nama properti harus jamak.
Kode yang disorot:
- DbSet<TEntity> Membuat properti untuk setiap set entitas. Dalam EF Core terminologi:
- Kumpulan entitas biasanya sesuai dengan tabel database.
- Entitas sesuai dengan baris dalam tabel.
- Panggilan OnModelCreating.
OnModelCreating
:- Dipanggil ketika
SchoolContext
telah diinisialisasi tetapi sebelum model diamankan dan digunakan untuk menginisialisasi konteks. - Diperlukan karena nanti dalam tutorial
Student
entitas akan memiliki referensi ke entitas lain.
- Dipanggil ketika
Kami berharap dapat memperbaiki masalah ini dalam rilis mendatang.
Program.cs
ASP.NET Core dibangun dengan injeksi dependensi. Layanan seperti SchoolContext
terdaftar dengan injeksi dependensi selama pengaktifan aplikasi. Komponen yang memerlukan layanan ini, seperti Razor Pages, disediakan layanan ini melalui parameter konstruktor. Kode konstruktor yang mendapatkan instans konteks database ditampilkan nanti dalam tutorial.
Alat perancah secara otomatis mendaftarkan kelas konteks dengan kontainer injeksi dependensi.
Garis yang disorot berikut ditambahkan oleh perancah:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
Nama string koneksi diteruskan ke konteks dengan memanggil metode pada DbContextOptions objek. Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca string koneksi dari appsettings.json
atau appsettings.Development.json
file.
Menambahkan filter pengecualian database
Tambahkan AddDatabaseDeveloperPageExceptionFilter dan UseMigrationsEndPoint seperti yang ditunjukkan dalam kode berikut:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
Tambahkan paket NuGet Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.
Di Konsol Manajer Paket, masukkan yang berikut ini untuk menambahkan paket NuGet:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Paket Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
NuGet menyediakan middleware inti ASP.NET untuk halaman kesalahan Core Kerangka Kerja Entitas. Middleware ini membantu mendeteksi dan mendiagnosis kesalahan dengan migrasi Entity Framework Core.
AddDatabaseDeveloperPageExceptionFilter
menyediakan informasi kesalahan yang bermanfaat di lingkungan pengembangan untuk kesalahan migrasi EF.
Buatlah databasenya
Perbarui Program.cs
untuk membuat database jika tidak ada:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Metode EnsureCreated ini tidak mengambil tindakan jika database untuk konteks ada. Jika tidak ada database, database dan skema akan dibuat. EnsureCreated
mengaktifkan alur kerja berikut untuk menangani perubahan model data:
- Menghapus database. Setiap data yang ada hilang.
- Ubah model data. Misalnya, tambahkan
EmailAddress
bidang. - Jalankan aplikasi.
EnsureCreated
membuat database dengan skema baru.
Alur kerja ini bekerja lebih awal dalam pengembangan ketika skema berkembang dengan cepat, selama data tidak perlu dipertahankan. Situasinya berbeda ketika data yang telah dimasukkan ke dalam database perlu dipertahankan. Ketika demikian, gunakan migrasi.
Kemudian dalam seri tutorial, database dihapus yang dibuat oleh EnsureCreated
dan migrasi digunakan. Database yang dibuat oleh EnsureCreated
tidak dapat diperbarui dengan menggunakan migrasi.
Menguji aplikasi
- Jalankan aplikasi.
- Pilih tautan Siswa lalu Buat Baru.
- Uji tautan Edit, Detail, dan Hapus.
Seed database
Metode ini EnsureCreated
membuat database kosong. Bagian ini menambahkan kode yang mengisi database dengan data pengujian.
Buat Data/DbInitializer.cs
dengan kode berikut:
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kode memeriksa apakah ada siswa dalam database. Jika tidak ada siswa, ia menambahkan data pengujian ke database. Ini membuat data pengujian dalam array daripada List<T>
koleksi untuk mengoptimalkan performa.
- Di
Program.cs
, hapus//
dariDbInitializer.Initialize
baris:
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
DbInitializer.Initialize(context);
}
Hentikan aplikasi jika sedang berjalan, dan jalankan perintah berikut di Package Manager Console (PMC):
Drop-Database -Confirm
Merespons dengan
Y
untuk menghapus database.
- Mulai ulang aplikasi.
- Pilih halaman Siswa untuk melihat data benih.
Menampilkan database
- Buka SQL Server Object Explorer (SSOX) dari menu Tampilan di Visual Studio.
- Di SSOX, pilih (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Nama database dihasilkan dari nama konteks yang disediakan sebelumnya ditambah tanda hubung dan GUID.
- Perluas simpul Tabel .
- Klik kanan tabel Siswa dan klik Tampilkan Data untuk melihat kolom yang dibuat dan baris yang disisipkan ke dalam tabel.
- Klik kanan tabel Siswa dan klik Tampilkan Kode untuk melihat bagaimana model memetakan
Student
keStudent
skema tabel.
Metode EF asinkron di aplikasi web ASP.NET Core
Pemrograman asinkron adalah mode default untuk ASP.NET Core dan EF Core.
Server web memiliki jumlah utas terbatas yang tersedia, dan dalam situasi beban tinggi semua utas yang tersedia mungkin digunakan. Ketika itu terjadi, server tidak dapat memproses permintaan baru sampai utas dikosongkan. Dengan kode sinkron, banyak utas mungkin diikat saat mereka tidak melakukan pekerjaan karena mereka menunggu I/O selesai. Dengan kode asinkron, ketika proses menunggu I/O selesai, utasnya dibebaskan untuk digunakan server untuk memproses permintaan lain. Akibatnya, kode asinkron memungkinkan sumber daya server digunakan lebih efisien, dan server dapat menangani lebih banyak lalu lintas tanpa penundaan.
Kode asinkron memang memperkenalkan sejumlah kecil overhead pada run time. Untuk situasi lalu lintas yang rendah, hit performa dapat diabaikan, sementara untuk situasi lalu lintas yang tinggi, potensi peningkatan performa sangat besar.
Dalam kode berikut, kata kunci asinkron , Task
nilai pengembalian, await
kata kunci, dan ToListAsync
metode membuat kode dijalankan secara asinkron.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Kata
async
kunci memberi tahu pengkompilasi untuk:- Hasilkan panggilan balik untuk bagian isi metode.
- Buat objek Tugas yang dikembalikan.
Task
Jenis pengembalian mewakili pekerjaan yang sedang berlangsung.- Kata
await
kunci menyebabkan pengkompilasi membagi metode menjadi dua bagian. Bagian pertama berakhir dengan operasi yang dimulai secara asinkron. Bagian kedua dimasukkan ke dalam metode panggilan balik yang dipanggil ketika operasi selesai. ToListAsync
adalah versi asinkron dariToList
metode ekstensi.
Beberapa hal yang perlu diperhatikan saat menulis kode asinkron yang menggunakan EF Core:
- Hanya pernyataan yang menyebabkan kueri atau perintah dikirim ke database yang dijalankan secara asinkron. Itu termasuk
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
, danSaveChangesAsync
. Ini tidak termasuk pernyataan yang hanya mengubahIQueryable
, sepertivar students = context.Students.Where(s => s.LastName == "Davolio")
. - Konteks EF Core tidak aman utas: jangan mencoba melakukan beberapa operasi secara paralel.
- Untuk memanfaatkan manfaat performa kode asinkron, verifikasi bahwa paket pustaka (seperti untuk penomoran halaman) menggunakan asinkron jika mereka memanggil EF Core metode yang mengirim kueri ke database.
Untuk informasi selengkapnya tentang pemrograman asinkron di .NET, lihat Gambaran Umum Asinkron dan Pemrograman asinkron dengan asinkron dan tunggu.
Peringatan
Implementasi asinkron Microsoft.Data.SqlClient memiliki beberapa masalah yang diketahui (#593, #601, dan lainnya). Jika Anda melihat masalah performa yang tidak terduga, coba gunakan eksekusi perintah sinkronisasi, terutama saat berhadapan dengan teks besar atau nilai biner.
Pertimbangan performa
Secara umum, halaman web tidak boleh memuat jumlah baris arbitrer. Kueri harus menggunakan paging atau pendekatan pembatasan. Misalnya, kueri sebelumnya dapat digunakan Take
untuk membatasi baris yang dikembalikan:
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Menghitung tabel besar dalam tampilan dapat mengembalikan respons HTTP 200 yang dibangun sebagian jika pengecualian database terjadi sebagian melalui enumerasi.
Penomoran dibahas nanti dalam tutorial.
Untuk informasi selengkapnya, lihat Pertimbangan performa (EF).
Langkah berikutnya
Gunakan SQLite untuk pengembangan, SQL Server untuk produksi
Ini adalah yang pertama dalam serangkaian tutorial yang menunjukkan cara menggunakan Entity Framework (EF) Core di aplikasi ASP.NET Core Razor Pages . Tutorial ini membangun situs web untuk Universitas Contoso fiktif. Situs ini mencakup fungsionalitas seperti penerimaan siswa, pembuatan kursus, dan penugasan instruktur. Tutorial ini menggunakan pendekatan pertama kode. Untuk informasi tentang mengikuti tutorial ini menggunakan pendekatan pertama database, lihat masalah Github ini.
Unduh atau lihat aplikasi yang telah selesai. Unduh instruksi.
Prasyarat
- Jika Anda baru Razor menggunakan Pages, buka seri tutorial Mulai menggunakan Razor Pages sebelum memulai yang ini.
- Visual Studio 2019 16.8 atau versi terbaru dengan beban kerja ASP.NET dan pengembangan web
- .NET 5.0 SDK
Mesin database
Instruksi Visual Studio menggunakan SQL Server LocalDB, versi SQL Server Express yang hanya berjalan di Windows.
Pemecahan Masalah
Jika Anda mengalami masalah yang tidak dapat Anda atasi, bandingkan kode Anda dengan proyek yang telah selesai. Cara yang baik untuk mendapatkan bantuan adalah dengan memposting pertanyaan ke StackOverflow.com, menggunakan tag ASP.NET Core atau EF Core tag .
Aplikasi sampel
Aplikasi yang dibangun dalam tutorial ini adalah situs web universitas dasar. Pengguna dapat melihat dan memperbarui informasi siswa, kursus, dan instruktur. Berikut adalah beberapa layar yang dibuat dalam tutorial.
Gaya UI situs ini didasarkan pada templat proyek bawaan. Fokus tutorial adalah pada cara menggunakan EF Core dengan ASP.NET Core, bukan cara menyesuaikan UI.
Opsional: Buat unduhan sampel
Langkah ini bersifat opsional. Membangun aplikasi yang telah selesai disarankan saat Anda memiliki masalah yang tidak dapat Anda selesaikan. Jika Anda mengalami masalah yang tidak dapat Anda atasi, bandingkan kode Anda dengan proyek yang telah selesai. Unduh instruksi.
Pilih ContosoUniversity.csproj
untuk membuka proyek.
- Bangun proyek.
- Di Package Manager Console (PMC) jalankan perintah berikut:
Update-Database
Jalankan proyek untuk menyemai database.
Membuat proyek aplikasi web
- Mulai Visual Studio dan pilih Buat proyek baru.
- Dalam dialog Buat proyek baru, pilih ASP.NET Core Web Application>Next.
- Dalam dialog Konfigurasikan proyek baru Anda, masukkan
ContosoUniversity
untuk Nama proyek. Penting untuk menggunakan nama yang tepat ini termasuk kapitalisasi, sehingga setiapnamespace
kecocokan saat kode disalin. - Pilih Buat.
- Dalam dialog Buat aplikasi web ASP.NET Core baru, pilih:
- .NET Core dan ASP.NET Core 5.0 di menu dropdown.
- ASP.NET Core Web App.
- Buat
Menyiapkan gaya situs
Salin dan tempel kode berikut ke Pages/Shared/_Layout.cshtml
dalam file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
File tata letak mengatur header situs, footer, dan menu. Kode sebelumnya membuat perubahan berikut:
- Setiap kemunculan "ContosoUniversity" ke "Contoso University". Ada tiga kejadian.
- Entri Home menu dan Privacy dihapus.
- Entri ditambahkan untuk Tentang, Siswa, Kursus, Instruktur, dan Departemen.
Di Pages/Index.cshtml
, ganti konten file dengan kode berikut:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
<a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
<a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
</p>
</div>
</div>
</div>
</div>
Kode sebelumnya menggantikan teks tentang ASP.NET Core dengan teks tentang aplikasi ini.
Jalankan aplikasi untuk memverifikasi bahwa home halaman muncul.
Model data
Bagian berikut membuat model data:
Siswa dapat mendaftar di sejumlah kursus, dan kursus dapat memiliki sejumlah siswa yang terdaftar di dalamnya.
Entitas Siswa
Buat folder Model di folder proyek.
Buat
Models/Student.cs
dengan kode berikut:using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Properti ID
menjadi kolom kunci utama tabel database yang sesuai dengan kelas ini. Secara default, EF Core menginterpretasikan properti yang dinamai ID
atau classnameID
sebagai kunci utama. Jadi nama alternatif yang dikenali secara otomatis untuk Student
kunci utama kelas adalah StudentID
. Untuk informasi selengkapnya, lihat EF Core - Kunci.
Properti Enrollments
adalah properti navigasi. Properti navigasi menyimpan entitas lain yang terkait dengan entitas ini. Dalam hal ini, Enrollments
properti Student
entitas memegang semua entitas yang terkait dengan Siswa tersebut Enrollment
. Misalnya, jika baris Siswa dalam database memiliki dua baris Pendaftaran terkait, properti navigasi berisi dua entitas Pendaftaran tersebut Enrollments
.
Dalam database, baris Pendaftaran terkait dengan baris Siswa jika kolomnya StudentID
berisi nilai ID siswa. Misalnya, baris Siswa memiliki ID=1. Baris Pendaftaran terkait akan memiliki StudentID
= 1. StudentID
adalah kunci asing dalam tabel Pendaftaran.
Properti Enrollments
didefinisikan sebagai ICollection<Enrollment>
karena mungkin ada beberapa entitas Pendaftaran terkait. Jenis koleksi lain dapat digunakan, seperti List<Enrollment>
atau HashSet<Enrollment>
. Saat ICollection<Enrollment>
digunakan, EF Core membuat HashSet<Enrollment>
koleksi secara default.
Entitas Pendaftaran
Buat Models/Enrollment.cs
dengan kode berikut:
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
[DisplayFormat(NullDisplayText = "No grade")]
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Properti EnrollmentID
adalah kunci utama; entitas ini menggunakan pola alih-alih ID
dengan sendirinyaclassnameID
. Untuk model data produksi, banyak pengembang memilih satu pola dan menggunakannya secara konsisten. Tutorial ini menggunakan keduanya hanya untuk menggambarkan bahwa keduanya berfungsi. Menggunakan ID
tanpa classname
mempermudah penerapan beberapa jenis perubahan model data.
Properti Grade
adalah enum
. Tanda tanya setelah Grade
deklarasi jenis menunjukkan bahwa Grade
properti dapat diubah ke null. Nilai null berbeda dari nilai nol—null berarti nilai belum diketahui atau belum ditetapkan.
Properti StudentID
adalah kunci asing, dan properti navigasi yang sesuai adalah Student
. Entitas Enrollment
dikaitkan dengan satu Student
entitas, sehingga properti berisi satu Student
entitas.
Properti CourseID
adalah kunci asing, dan properti navigasi yang sesuai adalah Course
. Entitas Enrollment
dikaitkan dengan satu Course
entitas.
EF Core menafsirkan properti sebagai kunci asing jika bernama <navigation property name><primary key property name>
. Misalnya,StudentID
adalah kunci asing untuk Student
properti navigasi, karena Student
kunci utama entitas adalah ID
. Properti kunci asing juga dapat diberi nama <primary key property name>
. Misalnya, CourseID
karena Course
kunci utama entitas adalah CourseID
.
Entitas Kursus
Buat Models/Course.cs
dengan kode berikut:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Properti Enrollments
adalah properti navigasi. Entitas Course
dapat terkait dengan sejumlah Enrollment
entitas.
Atribut DatabaseGenerated
ini memungkinkan aplikasi menentukan kunci utama daripada membuat database.
Buat proyek untuk memvalidasi bahwa tidak ada kesalahan pengkompilasi.
Halaman Siswa Perancah
Di bagian ini, alat perancah ASP.NET Core digunakan untuk menghasilkan:
- Sebuah EF Core
DbContext
kelas. Konteksnya adalah kelas utama yang mengoordinasikan fungsionalitas Kerangka Kerja Entitas untuk model data tertentu. Ini berasal dari Microsoft.EntityFrameworkCore.DbContext kelas . - Razor halaman yang menangani operasi Buat, Baca, Perbarui, dan Hapus (CRUD) untuk
Student
entitas.
- Buat folder Halaman/Siswa .
- Di Penjelajah Solusi, klik kanan folder Halaman/Siswa dan pilih Tambahkan>Item Perancah Baru.
- Dalam dialog Tambahkan Item Perancah Baru:
- Di tab sebelah kiri, pilih Halaman Umum >Razor terinstal >
- Pilih Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD)>ADD.
- Dalam dialog Tambahkan Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD):
- Di menu drop-down Kelas model, pilih Siswa (ContosoUniversity.Models).
- Di baris Kelas konteks data, pilih + tanda (plus).
- Ubah nama konteks data menjadi berakhiran
SchoolContext
daripadaContosoUniversityContext
. Nama konteks yang diperbarui:ContosoUniversity.Data.SchoolContext
- Pilih Tambahkan untuk menyelesaikan penambahan kelas konteks data.
- Pilih Tambahkan untuk menyelesaikan dialog Tambahkan Razor Halaman .
- Ubah nama konteks data menjadi berakhiran
Jika perancah gagal dengan kesalahan 'Install the package Microsoft.VisualStudio.Web.CodeGeneration.Design and try again.'
, jalankan alat perancah lagi atau lihat masalah GitHub ini.
Paket berikut diinstal secara otomatis:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
Jika langkah sebelumnya gagal, buat proyek dan coba lagi langkah perancah.
Proses perancah:
- Razor Membuat halaman di folder Halaman/Siswa:
Create.cshtml
danCreate.cshtml.cs
Delete.cshtml
danDelete.cshtml.cs
Details.cshtml
danDetails.cshtml.cs
Edit.cshtml
danEdit.cshtml.cs
Index.cshtml
danIndex.cshtml.cs
Data/SchoolContext.cs
Membuat .- Menambahkan konteks ke injeksi dependensi di
Startup.cs
. - Menambahkan database string koneksi ke
appsettings.json
.
Database string koneksi
Alat perancah menghasilkan string koneksi dalam appsettings.json
file.
string koneksi menentukan SQL Server LocalDB:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=CU-1;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB adalah versi ringan dari SQL Server Express Database Engine dan ditujukan untuk pengembangan aplikasi, bukan penggunaan produksi. Secara default, LocalDB membuat file .mdf di C:/Users/<user>
direktori.
Memperbarui kelas konteks database
Kelas utama yang mengoordinasikan EF Core fungsionalitas untuk model data tertentu adalah kelas konteks database. Konteks berasal dari Microsoft.EntityFrameworkCore.DbContext. Konteks menentukan entitas mana yang disertakan dalam model data. Dalam proyek ini, kelas diberi nama SchoolContext
.
Perbarui Data/SchoolContext.cs
dengan kode berikut:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Kode sebelumnya berubah dari tunggal DbSet<Student> Student
ke jamak DbSet<Student> Students
. Untuk membuat Razor kode Pages cocok dengan nama baru DBSet
, buat perubahan global dari: _context.Student.
ke: _context.Students.
Ada 8 kejadian.
Karena kumpulan entitas berisi beberapa entitas, banyak pengembang lebih suka DBSet
nama properti harus jamak.
Kode yang disorot:
- DbSet<TEntity> Membuat properti untuk setiap set entitas. Dalam EF Core terminologi:
- Kumpulan entitas biasanya sesuai dengan tabel database.
- Entitas sesuai dengan baris dalam tabel.
- Panggilan OnModelCreating.
OnModelCreating
:- Dipanggil ketika
SchoolContext
telah diinisialisasi tetapi sebelum model diamankan dan digunakan untuk menginisialisasi konteks. - Diperlukan karena nanti dalam tutorial
Student
entitas akan memiliki referensi ke entitas lain.
- Dipanggil ketika
Bangun proyek untuk memverifikasi tidak ada kesalahan kompilator.
Startup.cs
ASP.NET Core dibangun dengan injeksi dependensi. Layanan seperti SchoolContext
terdaftar dengan injeksi dependensi selama pengaktifan aplikasi. Komponen yang memerlukan layanan ini, seperti Razor Pages, disediakan layanan ini melalui parameter konstruktor. Kode konstruktor yang mendapatkan instans konteks database ditampilkan nanti dalam tutorial.
Alat perancah secara otomatis mendaftarkan kelas konteks dengan kontainer injeksi dependensi.
Garis yang disorot berikut ditambahkan oleh perancah:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
}
Nama string koneksi diteruskan ke konteks dengan memanggil metode pada DbContextOptions objek. Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca string koneksi dari appsettings.json
file.
Menambahkan filter pengecualian database
Tambahkan AddDatabaseDeveloperPageExceptionFilter dan UseMigrationsEndPoint seperti yang ditunjukkan dalam kode berikut:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
services.AddDatabaseDeveloperPageExceptionFilter();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Tambahkan paket NuGet Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.
Di Konsol Manajer Paket, masukkan yang berikut ini untuk menambahkan paket NuGet:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Paket Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
NuGet menyediakan middleware inti ASP.NET untuk halaman kesalahan Core Kerangka Kerja Entitas. Middleware ini membantu mendeteksi dan mendiagnosis kesalahan dengan migrasi Entity Framework Core.
AddDatabaseDeveloperPageExceptionFilter
menyediakan informasi kesalahan yang bermanfaat di lingkungan pengembangan untuk kesalahan migrasi EF.
Buatlah databasenya
Perbarui Program.cs
untuk membuat database jika tidak ada:
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
CreateDbIfNotExists(host);
host.Run();
}
private static void CreateDbIfNotExists(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Metode EnsureCreated ini tidak mengambil tindakan jika database untuk konteks ada. Jika tidak ada database, database dan skema akan dibuat. EnsureCreated
mengaktifkan alur kerja berikut untuk menangani perubahan model data:
- Menghapus database. Setiap data yang ada hilang.
- Ubah model data. Misalnya, tambahkan
EmailAddress
bidang. - Jalankan aplikasi.
EnsureCreated
membuat database dengan skema baru.
Alur kerja ini bekerja lebih awal dalam pengembangan ketika skema berkembang dengan cepat, selama data tidak perlu dipertahankan. Situasinya berbeda ketika data yang telah dimasukkan ke dalam database perlu dipertahankan. Ketika demikian, gunakan migrasi.
Kemudian dalam seri tutorial, database dihapus yang dibuat oleh EnsureCreated
dan migrasi digunakan. Database yang dibuat oleh EnsureCreated
tidak dapat diperbarui dengan menggunakan migrasi.
Menguji aplikasi
- Jalankan aplikasi.
- Pilih tautan Siswa lalu Buat Baru.
- Uji tautan Edit, Detail, dan Hapus.
Seed database
Metode ini EnsureCreated
membuat database kosong. Bagian ini menambahkan kode yang mengisi database dengan data pengujian.
Buat Data/DbInitializer.cs
dengan kode berikut:
using ContosoUniversity.Models;
using System;
using System.Linq;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kode memeriksa apakah ada siswa dalam database. Jika tidak ada siswa, ia menambahkan data pengujian ke database. Ini membuat data pengujian dalam array daripada List<T>
koleksi untuk mengoptimalkan performa.
Di
Program.cs
, hapus//
dariDbInitializer.Initialize
baris:context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Hentikan aplikasi jika sedang berjalan, dan jalankan perintah berikut di Package Manager Console (PMC):
Drop-Database -Confirm
Merespons dengan
Y
untuk menghapus database.
- Mulai ulang aplikasi.
- Pilih halaman Siswa untuk melihat data benih.
Menampilkan database
- Buka SQL Server Object Explorer (SSOX) dari menu Tampilan di Visual Studio.
- Di SSOX, pilih (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Nama database dihasilkan dari nama konteks yang disediakan sebelumnya ditambah tanda hubung dan GUID.
- Perluas simpul Tabel .
- Klik kanan tabel Siswa dan klik Tampilkan Data untuk melihat kolom yang dibuat dan baris yang disisipkan ke dalam tabel.
- Klik kanan tabel Siswa dan klik Tampilkan Kode untuk melihat bagaimana model memetakan
Student
keStudent
skema tabel.
Kode asinkron
Pemrograman asinkron adalah mode default untuk ASP.NET Core dan EF Core.
Server web memiliki jumlah utas terbatas yang tersedia, dan dalam situasi beban tinggi semua utas yang tersedia mungkin digunakan. Ketika itu terjadi, server tidak dapat memproses permintaan baru sampai utas dikosongkan. Dengan kode sinkron, banyak utas mungkin diikat saat mereka tidak melakukan pekerjaan karena mereka menunggu I/O selesai. Dengan kode asinkron, ketika proses menunggu I/O selesai, utasnya dibebaskan untuk digunakan server untuk memproses permintaan lain. Akibatnya, kode asinkron memungkinkan sumber daya server digunakan lebih efisien, dan server dapat menangani lebih banyak lalu lintas tanpa penundaan.
Kode asinkron memang memperkenalkan sejumlah kecil overhead pada run time. Untuk situasi lalu lintas yang rendah, hit performa dapat diabaikan, sementara untuk situasi lalu lintas yang tinggi, potensi peningkatan performa sangat besar.
Dalam kode berikut, kata kunci asinkron , Task
nilai pengembalian, await
kata kunci, dan ToListAsync
metode membuat kode dijalankan secara asinkron.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Kata
async
kunci memberi tahu pengkompilasi untuk:- Hasilkan panggilan balik untuk bagian isi metode.
- Buat objek Tugas yang dikembalikan.
Task
Jenis pengembalian mewakili pekerjaan yang sedang berlangsung.- Kata
await
kunci menyebabkan pengkompilasi membagi metode menjadi dua bagian. Bagian pertama berakhir dengan operasi yang dimulai secara asinkron. Bagian kedua dimasukkan ke dalam metode panggilan balik yang dipanggil ketika operasi selesai. ToListAsync
adalah versi asinkron dariToList
metode ekstensi.
Beberapa hal yang perlu diperhatikan saat menulis kode asinkron yang menggunakan EF Core:
- Hanya pernyataan yang menyebabkan kueri atau perintah dikirim ke database yang dijalankan secara asinkron. Itu termasuk
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
, danSaveChangesAsync
. Ini tidak termasuk pernyataan yang hanya mengubahIQueryable
, sepertivar students = context.Students.Where(s => s.LastName == "Davolio")
. - Konteks EF Core tidak aman utas: jangan mencoba melakukan beberapa operasi secara paralel.
- Untuk memanfaatkan manfaat performa kode asinkron, verifikasi bahwa paket pustaka (seperti untuk penomoran halaman) menggunakan asinkron jika mereka memanggil EF Core metode yang mengirim kueri ke database.
Untuk informasi selengkapnya tentang pemrograman asinkron di .NET, lihat Gambaran Umum Asinkron dan Pemrograman asinkron dengan asinkron dan tunggu.
Pertimbangan performa
Secara umum, halaman web tidak boleh memuat jumlah baris arbitrer. Kueri harus menggunakan paging atau pendekatan pembatasan. Misalnya, kueri sebelumnya dapat digunakan Take
untuk membatasi baris yang dikembalikan:
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Menghitung tabel besar dalam tampilan dapat mengembalikan respons HTTP 200 yang dibangun sebagian jika pengecualian database terjadi sebagian melalui enumerasi.
MaxModelBindingCollectionSize default ke 1024. Kumpulan MaxModelBindingCollectionSize
kode berikut :
public void ConfigureServices(IServiceCollection services)
{
var myMaxModelBindingCollectionSize = Convert.ToInt32(
Configuration["MyMaxModelBindingCollectionSize"] ?? "100");
services.Configure<MvcOptions>(options =>
options.MaxModelBindingCollectionSize = myMaxModelBindingCollectionSize);
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
services.AddDatabaseDeveloperPageExceptionFilter();
}
Lihat Konfigurasi untuk informasi tentang pengaturan konfigurasi seperti MyMaxModelBindingCollectionSize
.
Penomoran dibahas nanti dalam tutorial.
Untuk informasi selengkapnya, lihat Pertimbangan performa (EF).
Pengelogan SQL Core Kerangka Kerja Entitas
Konfigurasi pengelogan biasanya disediakan oleh bagian Logging
dari file appsettings.{Environment}.json
. Untuk mencatat pernyataan SQL, tambahkan "Microsoft.EntityFrameworkCore.Database.Command": "Information"
ke appsettings.Development.json
file:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
}
},
"AllowedHosts": "*"
}
Dengan JSON sebelumnya, pernyataan SQL ditampilkan pada baris perintah dan di jendela output Visual Studio.
Untuk informasi selengkapnya, lihat Pengelogan di .NET Core dan ASP.NET Core dan masalah GitHub ini.
Langkah berikutnya
Gunakan SQLite untuk pengembangan, SQL Server untuk produksi
Ini adalah yang pertama dalam serangkaian tutorial yang menunjukkan cara menggunakan Entity Framework (EF) Core di aplikasi ASP.NET Core Razor Pages . Tutorial ini membangun situs web untuk Universitas Contoso fiktif. Situs ini mencakup fungsionalitas seperti penerimaan siswa, pembuatan kursus, dan penugasan instruktur. Tutorial ini menggunakan pendekatan pertama kode. Untuk informasi tentang mengikuti tutorial ini menggunakan pendekatan pertama database, lihat masalah Github ini.
Unduh atau lihat aplikasi yang telah selesai. Unduh instruksi.
Prasyarat
- Jika Anda baru Razor menggunakan Pages, buka seri tutorial Mulai menggunakan Razor Pages sebelum memulai yang ini.
- Visual Studio 2019 dengan beban kerja pengembangan ASP.NET dan web
- .NET Core 3.0 SDK
Mesin database
Instruksi Visual Studio menggunakan SQL Server LocalDB, versi SQL Server Express yang hanya berjalan di Windows.
Instruksi Visual Studio Code menggunakan SQLite, mesin database lintas platform.
Jika Anda memilih untuk menggunakan SQLite, unduh dan instal alat pihak ketiga untuk mengelola dan melihat database SQLite, seperti Browser DB untuk SQLite.
Pemecahan Masalah
Jika Anda mengalami masalah yang tidak dapat Anda atasi, bandingkan kode Anda dengan proyek yang telah selesai. Cara yang baik untuk mendapatkan bantuan adalah dengan memposting pertanyaan ke StackOverflow.com, menggunakan tag ASP.NET Core atau EF Core tag .
Aplikasi sampel
Aplikasi yang dibangun dalam tutorial ini adalah situs web universitas dasar. Pengguna dapat melihat dan memperbarui informasi siswa, kursus, dan instruktur. Berikut adalah beberapa layar yang dibuat dalam tutorial.
Gaya UI situs ini didasarkan pada templat proyek bawaan. Fokus tutorial adalah pada cara menggunakan EF Core, bukan cara menyesuaikan UI.
Ikuti tautan di bagian atas halaman untuk mendapatkan kode sumber untuk proyek yang telah selesai. Folder cu30 memiliki kode untuk tutorial versi ASP.NET Core 3.0. File yang mencerminkan status kode untuk tutorial 1-7 dapat ditemukan di folder cu30snapshots .
Untuk menjalankan aplikasi setelah mengunduh proyek yang telah selesai:
Bangun proyek.
Di Package Manager Console (PMC) jalankan perintah berikut:
Update-Database
Jalankan proyek untuk menyemai database.
Membuat proyek aplikasi web
- Dari menu File Visual Studio, pilih Proyek Baru>.
- Pilih ASP.NET Core Web Application.
- Beri nama proyek ContosoUniversity. Penting untuk menggunakan nama yang tepat ini termasuk kapitalisasi, sehingga namespace cocok saat kode disalin dan ditempelkan.
- Pilih .NET Core dan ASP.NET Core 3.0 di menu dropdown, lalu pilih Aplikasi Web.
Menyiapkan gaya situs
Siapkan header situs, footer, dan menu dengan memperbarui Pages/Shared/_Layout.cshtml
:
Ubah setiap kemunculan "ContosoUniversity" menjadi "Contoso University". Ada tiga kejadian.
Home Hapus entri menu dan Privacy , dan tambahkan entri untuk Tentang, Siswa, Kursus, Instruktur, dan Departemen.
Perubahan disorot.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Di Pages/Index.cshtml
, ganti konten file dengan kode berikut untuk mengganti teks tentang ASP.NET Core dengan teks tentang aplikasi ini:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
<a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
<a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
</p>
</div>
</div>
</div>
</div>
Jalankan aplikasi untuk memverifikasi bahwa home halaman muncul.
Model data
Bagian berikut membuat model data:
Siswa dapat mendaftar di sejumlah kursus, dan kursus dapat memiliki sejumlah siswa yang terdaftar di dalamnya.
Entitas Siswa
Buat folder Model di folder proyek.
Buat
Models/Student.cs
dengan kode berikut:using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Properti ID
menjadi kolom kunci utama tabel database yang sesuai dengan kelas ini. Secara default, EF Core menginterpretasikan properti yang dinamai ID
atau classnameID
sebagai kunci utama. Jadi nama alternatif yang dikenali secara otomatis untuk Student
kunci utama kelas adalah StudentID
. Untuk informasi selengkapnya, lihat EF Core - Kunci.
Properti Enrollments
adalah properti navigasi. Properti navigasi menyimpan entitas lain yang terkait dengan entitas ini. Dalam hal ini, Enrollments
properti Student
entitas memegang semua entitas yang terkait dengan Siswa tersebut Enrollment
. Misalnya, jika baris Siswa dalam database memiliki dua baris Pendaftaran terkait, properti navigasi berisi dua entitas Pendaftaran tersebut Enrollments
.
Dalam database, baris Pendaftaran terkait dengan baris Siswa jika kolom StudentID-nya berisi nilai ID siswa. Misalnya, baris Siswa memiliki ID=1. Baris Pendaftaran terkait akan memiliki StudentID = 1. StudentID adalah kunci asing dalam tabel Pendaftaran.
Properti Enrollments
didefinisikan sebagai ICollection<Enrollment>
karena mungkin ada beberapa entitas Pendaftaran terkait. Anda dapat menggunakan jenis koleksi lain, seperti List<Enrollment>
atau HashSet<Enrollment>
. Saat ICollection<Enrollment>
digunakan, EF Core membuat HashSet<Enrollment>
koleksi secara default.
Entitas Pendaftaran
Buat Models/Enrollment.cs
dengan kode berikut:
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Properti EnrollmentID
adalah kunci utama; entitas ini menggunakan pola alih-alih ID
dengan sendirinyaclassnameID
. Untuk model data produksi, pilih satu pola dan gunakan secara konsisten. Tutorial ini menggunakan keduanya hanya untuk menggambarkan bahwa keduanya berfungsi. Menggunakan ID
tanpa classname
mempermudah penerapan beberapa jenis perubahan model data.
Properti Grade
adalah enum
. Tanda tanya setelah Grade
deklarasi jenis menunjukkan bahwa Grade
properti dapat diubah ke null. Nilai null berbeda dari nilai nol—null berarti nilai belum diketahui atau belum ditetapkan.
Properti StudentID
adalah kunci asing, dan properti navigasi yang sesuai adalah Student
. Entitas Enrollment
dikaitkan dengan satu Student
entitas, sehingga properti berisi satu Student
entitas.
Properti CourseID
adalah kunci asing, dan properti navigasi yang sesuai adalah Course
. Entitas Enrollment
dikaitkan dengan satu Course
entitas.
EF Core menafsirkan properti sebagai kunci asing jika bernama <navigation property name><primary key property name>
. Misalnya,StudentID
adalah kunci asing untuk Student
properti navigasi, karena Student
kunci utama entitas adalah ID
. Properti kunci asing juga dapat diberi nama <primary key property name>
. Misalnya, CourseID
karena Course
kunci utama entitas adalah CourseID
.
Entitas Kursus
Buat Models/Course.cs
dengan kode berikut:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Properti Enrollments
adalah properti navigasi. Entitas Course
dapat terkait dengan sejumlah Enrollment
entitas.
Atribut DatabaseGenerated
ini memungkinkan aplikasi menentukan kunci utama daripada membuat database.
Buat proyek untuk memvalidasi bahwa tidak ada kesalahan pengkompilasi.
Halaman Siswa Perancah
Di bagian ini, Anda menggunakan alat perancah ASP.NET Core untuk menghasilkan:
- Kelas EF Corekonteks . Konteksnya adalah kelas utama yang mengoordinasikan fungsionalitas Kerangka Kerja Entitas untuk model data tertentu. Ini berasal dari
Microsoft.EntityFrameworkCore.DbContext
kelas . - Razor halaman yang menangani operasi Buat, Baca, Perbarui, dan Hapus (CRUD) untuk
Student
entitas.
- Buat folder Siswa di folder Halaman .
- Di Penjelajah Solusi, klik kanan folder Halaman/Siswa dan pilih Tambahkan>Item Perancah Baru.
- Dalam dialog Tambahkan Perancah, pilih Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD)>ADD.
- Dalam dialog Tambahkan Razor Halaman menggunakan Kerangka Kerja Entitas (CRUD):
- Di menu drop-down Kelas model, pilih Siswa (ContosoUniversity.Models).
- Di baris Kelas konteks data, pilih + tanda (plus).
- Ubah nama konteks data dari ContosoUniversity.Models.ContosoUniversityContext menjadi ContosoUniversity.Data.SchoolContext.
- Pilih Tambahkan.
Paket berikut diinstal secara otomatis:
Microsoft.VisualStudio.Web.CodeGeneration.Design
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.Extensions.Logging.Debug
Microsoft.EntityFrameworkCore.Tools
Jika Anda memiliki masalah dengan langkah sebelumnya, buat proyek dan coba lagi langkah perancah.
Proses perancah:
- Razor Membuat halaman di folder Halaman/Siswa:
Create.cshtml
danCreate.cshtml.cs
Delete.cshtml
danDelete.cshtml.cs
Details.cshtml
danDetails.cshtml.cs
Edit.cshtml
danEdit.cshtml.cs
Index.cshtml
danIndex.cshtml.cs
Data/SchoolContext.cs
Membuat .- Menambahkan konteks ke injeksi dependensi di
Startup.cs
. - Menambahkan database string koneksi ke
appsettings.json
.
Database string koneksi
File appsettings.json
menentukan string koneksi SQL Server LocalDB.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext6;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB adalah versi ringan dari SQL Server Express Database Engine dan ditujukan untuk pengembangan aplikasi, bukan penggunaan produksi. Secara default, LocalDB membuat file .mdf di C:/Users/<user>
direktori.
Memperbarui kelas konteks database
Kelas utama yang mengoordinasikan EF Core fungsionalitas untuk model data tertentu adalah kelas konteks database. Konteks berasal dari Microsoft.EntityFrameworkCore.DbContext. Konteks menentukan entitas mana yang disertakan dalam model data. Dalam proyek ini, kelas diberi nama SchoolContext
.
Perbarui Data/SchoolContext.cs
dengan kode berikut:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Kode yang disorot DbSet<TEntity> membuat properti untuk setiap set entitas. Dalam EF Core terminologi:
- Kumpulan entitas biasanya sesuai dengan tabel database.
- Entitas sesuai dengan baris dalam tabel.
Karena kumpulan entitas berisi beberapa entitas, properti DBSet harus berupa nama jamak. Karena alat perancah membuatStudent
DBSet, langkah ini mengubahnya menjadi jamak Students
.
Untuk membuat Razor kode Pages cocok dengan nama DBSet baru, buat perubahan global di seluruh proyek menjadi _context.Student
_context.Students
. Ada 8 kejadian.
Bangun proyek untuk memverifikasi tidak ada kesalahan kompilator.
Startup.cs
ASP.NET Core dibangun dengan injeksi dependensi. Layanan (seperti EF Core konteks database) terdaftar dengan injeksi dependensi selama startup aplikasi. Komponen yang memerlukan layanan ini (seperti Razor Pages) disediakan layanan ini melalui parameter konstruktor. Kode konstruktor yang mendapatkan instans konteks database ditampilkan nanti dalam tutorial.
Alat perancah secara otomatis mendaftarkan kelas konteks dengan kontainer injeksi dependensi.
Dalam
ConfigureServices
, garis yang disorot ditambahkan oleh perancah:public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SchoolContext"))); }
Nama string koneksi diteruskan ke konteks dengan memanggil metode pada DbContextOptions objek. Untuk pengembangan lokal, sistem konfigurasi ASP.NET Core membaca string koneksi dari appsettings.json
file.
Buatlah databasenya
Perbarui Program.cs
untuk membuat database jika tidak ada:
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
CreateDbIfNotExists(host);
host.Run();
}
private static void CreateDbIfNotExists(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Metode EnsureCreated ini tidak mengambil tindakan jika database untuk konteks ada. Jika tidak ada database, database dan skema akan dibuat. EnsureCreated
mengaktifkan alur kerja berikut untuk menangani perubahan model data:
- Menghapus database. Setiap data yang ada hilang.
- Ubah model data. Misalnya, tambahkan
EmailAddress
bidang. - Jalankan aplikasi.
EnsureCreated
membuat database dengan skema baru.
Alur kerja ini bekerja dengan baik di awal pengembangan ketika skema berkembang dengan cepat, selama Anda tidak perlu mempertahankan data. Situasinya berbeda ketika data yang telah dimasukkan ke dalam database perlu dipertahankan. Ketika demikian, gunakan migrasi.
Kemudian dalam seri tutorial, Anda menghapus database yang dibuat oleh EnsureCreated
dan menggunakan migrasi sebagai gantinya. Database yang dibuat oleh EnsureCreated
tidak dapat diperbarui dengan menggunakan migrasi.
Menguji aplikasi
- Jalankan aplikasi.
- Pilih tautan Siswa lalu Buat Baru.
- Uji tautan Edit, Detail, dan Hapus.
Seed database
Metode ini EnsureCreated
membuat database kosong. Bagian ini menambahkan kode yang mengisi database dengan data pengujian.
Buat Data/DbInitializer.cs
dengan kode berikut:
using ContosoUniversity.Data;
using ContosoUniversity.Models;
using System;
using System.Linq;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
context.Database.EnsureCreated();
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kode memeriksa apakah ada siswa dalam database. Jika tidak ada siswa, ia menambahkan data pengujian ke database. Ini membuat data pengujian dalam array daripada List<T>
koleksi untuk mengoptimalkan performa.
Di
Program.cs
, gantiEnsureCreated
panggilan denganDbInitializer.Initialize
panggilan:// context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Hentikan aplikasi jika sedang berjalan, dan jalankan perintah berikut di Package Manager Console (PMC):
Drop-Database
Mulai ulang aplikasi.
Pilih halaman Siswa untuk melihat data benih.
Menampilkan database
- Buka SQL Server Object Explorer (SSOX) dari menu Tampilan di Visual Studio.
- Di SSOX, pilih (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Nama database dihasilkan dari nama konteks yang Anda berikan sebelumnya ditambah tanda hubung dan GUID.
- Perluas simpul Tabel .
- Klik kanan tabel Siswa dan klik Tampilkan Data untuk melihat kolom yang dibuat dan baris yang disisipkan ke dalam tabel.
- Klik kanan tabel Siswa dan klik Tampilkan Kode untuk melihat bagaimana model memetakan
Student
keStudent
skema tabel.
Kode asinkron
Pemrograman asinkron adalah mode default untuk ASP.NET Core dan EF Core.
Server web memiliki jumlah utas terbatas yang tersedia, dan dalam situasi beban tinggi semua utas yang tersedia mungkin digunakan. Ketika itu terjadi, server tidak dapat memproses permintaan baru sampai utas dikosongkan. Dengan kode sinkron, banyak utas mungkin diikat sementara mereka tidak benar-benar melakukan pekerjaan apa pun karena mereka menunggu I/O selesai. Dengan kode asinkron, ketika proses menunggu I/O selesai, utasnya dibebaskan untuk digunakan server untuk memproses permintaan lain. Akibatnya, kode asinkron memungkinkan sumber daya server digunakan lebih efisien, dan server dapat menangani lebih banyak lalu lintas tanpa penundaan.
Kode asinkron memang memperkenalkan sejumlah kecil overhead pada run time. Untuk situasi lalu lintas yang rendah, hit performa dapat diabaikan, sementara untuk situasi lalu lintas yang tinggi, potensi peningkatan performa sangat besar.
Dalam kode berikut, kata kunci asinkron , Task<T>
nilai pengembalian, await
kata kunci, dan ToListAsync
metode membuat kode dijalankan secara asinkron.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Kata
async
kunci memberi tahu pengkompilasi untuk:- Hasilkan panggilan balik untuk bagian isi metode.
- Buat objek Tugas yang dikembalikan.
Task<T>
Jenis pengembalian mewakili pekerjaan yang sedang berlangsung.- Kata
await
kunci menyebabkan pengkompilasi membagi metode menjadi dua bagian. Bagian pertama berakhir dengan operasi yang dimulai secara asinkron. Bagian kedua dimasukkan ke dalam metode panggilan balik yang dipanggil ketika operasi selesai. ToListAsync
adalah versi asinkron dariToList
metode ekstensi.
Beberapa hal yang perlu diperhatikan saat menulis kode asinkron yang menggunakan EF Core:
- Hanya pernyataan yang menyebabkan kueri atau perintah dikirim ke database yang dijalankan secara asinkron. Itu termasuk
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
, danSaveChangesAsync
. Ini tidak termasuk pernyataan yang hanya mengubahIQueryable
, sepertivar students = context.Students.Where(s => s.LastName == "Davolio")
. - Konteks EF Core tidak aman utas: jangan mencoba melakukan beberapa operasi secara paralel.
- Untuk memanfaatkan manfaat performa kode asinkron, verifikasi bahwa paket pustaka (seperti untuk penomoran halaman) menggunakan asinkron jika mereka memanggil EF Core metode yang mengirim kueri ke database.
Untuk informasi selengkapnya tentang pemrograman asinkron di .NET, lihat Gambaran Umum Asinkron dan Pemrograman asinkron dengan asinkron dan tunggu.
Langkah berikutnya
ASP.NET Core