Nguon: Microsoft Learn · .NET 8.0

Phần 5: Làm việc với Database trong ứng dụng ASP.NET Core MVC

Nguồn: Part 5, work with a database in an ASP.NET Core MVC app

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:

Đ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

csharp
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:

json
"ConnectionStrings": {
  "MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
}

Visual Studio Code

csharp
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:

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:

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:

csharp
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.

csharp
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.

csharp
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:

csharp
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