Phần 5: Làm việc với Database trong ứng dụng ASP.NET Core MVC
Giới thiệu
Phần này của loạt bài hướng dẫn tập trung vào việc làm việc với SQL database trong ứng dụng ASP.NET Core MVC của bạn.
Bạn sẽ học cách:
- Đăng ký và cấu hình Entity Framework Core (EF Core) database context cho ứng dụng ASP.NET Core MVC của bạn.
- Làm việc với database connection string (chuỗi kết nối database) cho local development (phát triển cục bộ).
- Sử dụng SQL Server Express LocalDB cho development và kiểm tra database và dữ liệu của bạn bằng SQL Server Object Explorer.
- Seed (gieo dữ liệu mẫu) database với dữ liệu mẫu ban đầu.
Điều kiện tiên quyết
Hướng dẫn này sử dụng database bạn đã thiết lập trong bước trước: Phần 4, thêm model vào ứng dụng ASP.NET Core MVC.
Làm việc với database context
Đối tượng MvcMovieContext xử lý nhiệm vụ kết nối với database và ánh xạ các đối tượng Movie với các bản ghi database. Database context được đăng ký với container Dependency Injection trong tệp Program.cs:
Visual Studio
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));Hệ thống Configuration của ASP.NET Core đọc key ConnectionString. Cho local development, nó lấy connection string từ tệp appsettings.json:
"ConnectionStrings": {
"MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
}Visual Studio Code
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));Hệ thống Configuration của ASP.NET Core đọc ConnectionString. Cho local development, nó lấy connection string từ tệp appsettings.json:
"ConnectionStrings": {
"MvcMovieContext": "Data Source=MvcMovie.db"
}Bài viết này sử dụng local database không yêu cầu người dùng phải authenticated (xác thực). Production apps (ứng dụng sản xuất) nên sử dụng luồng authentication (xác thực) an toàn nhất có sẵn. Để biết thêm thông tin về authentication cho các ứng dụng test và production đã triển khai, xem Secure authentication flows.
SQL Server Express LocalDB (Visual Studio)
LocalDB:
- Là phiên bản nhẹ của SQL Server Express Database Engine, được cài đặt mặc định với Visual Studio.
- Khởi động theo yêu cầu bằng cách sử dụng connection string.
- Được nhắm mục tiêu cho phát triển chương trình. Nó chạy ở user mode (chế độ người dùng), vì vậy không có cấu hình phức tạp.
- Mặc định tạo tệp .mdf trong thư mục C:/Users/{user}.
Kiểm tra database
Từ menu View, mở SQL Server Object Explorer (SSOX).
Nhấp chuột phải vào bảng Movie (dbo.Movie) > View Designer
Lưu ý biểu tượng key bên cạnh ID. Theo mặc định, EF làm cho thuộc tính có tên ID là primary key (khóa chính).
Nhấp chuột phải vào bảng Movie > View Data
SQLite (Visual Studio Code)
Trang web SQLite nêu rõ:
SQLite là một SQL database engine độc lập, độ tin cậy cao, nhúng, đầy đủ tính năng, thuộc phạm vi công cộng. SQLite là database engine được sử dụng nhiều nhất trên thế giới.
Có nhiều third-party tools (công cụ bên thứ ba) bạn có thể tải xuống để quản lý và xem SQLite database. Có thể sử dụng DB Browser for SQLite.
Đối với hướng dẫn này, bạn sử dụng tính năng EF Core migrations (di chuyển) khi có thể. Migrations cập nhật database schema để khớp với các thay đổi trong data model. Tuy nhiên, migrations chỉ có thể thực hiện các loại thay đổi mà EF Core provider hỗ trợ, và khả năng của SQLite provider bị giới hạn. Ví dụ, thêm cột được hỗ trợ, nhưng xóa hoặc thay đổi cột thì không. Nếu migration được tạo để xóa hoặc thay đổi cột, lệnh ef migrations add thành công nhưng lệnh ef database update thất bại. Do những hạn chế này, hướng dẫn này không sử dụng migrations cho các thay đổi SQLite schema. Thay vào đó, khi schema thay đổi, bạn drop (xóa) và re-create (tạo lại) database.
Cách giải quyết cho các hạn chế SQLite là viết thủ công migration code để thực hiện table rebuild (xây dựng lại bảng) khi có gì đó trong bảng thay đổi. Việc rebuild bảng bao gồm: - Tạo bảng mới. - Sao chép dữ liệu từ bảng cũ vào bảng mới. - Drop bảng cũ. - Đổi tên bảng mới.
Seed (Gieo dữ liệu mẫu) database
Tạo class mới tên SeedData trong thư mục Models. Thay thế code được tạo bằng nội dung sau:
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MvcMovie.Data;
using System;
using System.Linq;
namespace MvcMovie.Models;
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new MvcMovieContext(
serviceProvider.GetRequiredService<
DbContextOptions<MvcMovieContext>>()))
{
// Look for any movies.
if (context.Movie.Any())
{
return; // DB has been seeded
}
context.Movie.AddRange(
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-2-12"),
Genre = "Romantic Comedy",
Price = 7.99M
},
new Movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new Movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new Movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
context.SaveChanges();
}
}
}Nếu có bất kỳ phim nào trong database, seed initializer (bộ khởi tạo dữ liệu mẫu) sẽ return và không thêm phim nào.
if (context.Movie.Any())
{
return; // DB has been seeded.
}Thêm seed initializer
Visual Studio
Thay thế nội dung của Program.cs bằng code sau. Code mới được tô sáng.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MvcMovie.Data;
using MvcMovie.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();Xóa tất cả bản ghi trong database. Bạn có thể thực hiện điều này bằng các link delete trong trình duyệt hoặc từ SSOX.
Kiểm tra ứng dụng. Buộc ứng dụng khởi tạo, gọi code trong tệp Program.cs, để seed method chạy. Để buộc khởi tạo, đóng cửa sổ command prompt mà Visual Studio đã mở và khởi động lại bằng cách nhấn Ctrl+F5.
Visual Studio Code
Cập nhật Program.cs với code được tô sáng sau:
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MvcMovie.Data;
using MvcMovie.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();Xóa tất cả bản ghi trong database.
Kiểm tra ứng dụng. Dừng và khởi động lại ứng dụng để phương thức SeedData.Initialize chạy và seed database.
Ứng dụng hiển thị dữ liệu đã được seed.
Bạn có thể không nhập được dấu phẩy thập phân trong các trường decimal. Để hỗ trợ jQuery validation cho các locale không phải tiếng Anh sử dụng dấu phẩy (",") cho dấu thập phân, và các định dạng ngày không phải tiếng Anh Mỹ, bạn phải thực hiện các bước để globalize (toàn cầu hóa) ứng dụng. Xem GitHub comment 4076 để biết hướng dẫn thêm decimal comma.
Trước: Thêm Model | Tiếp theo: Thêm các phương thức controller và views