第 2 部分,在 ASP.NET Core 中向 Razor 页面应用添加模型

Note

此版本不是本文的最新版本。 有关当前版本,请参阅 本文的 .NET 10 版本

Warning

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅 本文的 .NET 10 版本

在本教程中,将添加用于管理数据库中电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

添加数据模型

  1. 解决方案资源管理器中,右键单击 RazorPagesMovie 项目。 选择“添加>新文件夹。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models;
    
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType] 属性,用于指定 ReleaseDate 属性中的数据类型。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而不显示任何时间信息。
  • string后加问号表示该属性可为 null。 有关详细信息,请参阅可为空引用类型

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在本部分中,你将搭建电影模型基架。 脚手架工具为电影模型生成用于创建、读取、更新和删除(CRUD)操作的页面。

  1. 创建“Pages/Movies”文件夹

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  2. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

新建基架项。

  1. 在“添加新脚手架”对话框中,选择Razor“使用 Entity Framework 的页面 (CRUD)”>,然后单击“添加”

添加基架。

  1. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
      2. 在“数据库提供程序”下拉列表中,选择“SQL Server”。
    3. 选择 并添加

    添加 Razor 页面。

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

下一教程介绍了已创建的文件。

基架进程将以下突出显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages()
   .WithStaticAssets();

app.Run();

本教程稍后将介绍这些 Program.cs 更改。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用的数据模型保持同步。 此方法保留数据库中的现有数据。

在本部分中,使用 包管理器控制台 (PMC)窗口执行以下作:

  • 添加初始迁移。

  • 使用初始迁移来更新数据库。

  • 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单。

  • 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    
  • Add-Migration 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 参数 InitialCreate 命名迁移。 可以使用任何名称,但按照约定选择描述迁移的名称。

将显示以下警告,可在后续步骤中解决该警告:

实体类型“Movie”上没有为小数列“Price”指定存储类型。 如果值不符合默认精度和比例,则会导致值被无提示或警告地截断。 使用“HasColumnType”显式指定可以容纳“OnModelCreating”中的所有值的 SQL Server 列类型,使用“HasPrecision”指定精度和缩放,或使用“HasConversion”配置值转换器。

  • 在 PMC 中,输入以下命令:

    Update-Database
    

    未应用的迁移中,Update-Database 命令运行 Up 方法。 在这种情况下,命令在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

数据上下文 RazorPagesMovieContext

  • 派生自 Microsoft.EntityFrameworkCore.DbContext
  • 指定数据模型中包含哪些实体。
  • 协调 EF Core 模型的“创建”、“读取”、“更新”和“ Movie 删除”等功能。

生成的文件 Data/RazorPagesMovieContext.cs 中的 RazorPagesMovieContext 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; } = default!;
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

连接字符串的名称通过对 DbContextOptions 对象调用方法传递给上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 新建 链接。

创建页面。

Note

可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  1. 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动期间,使用依赖注入注册服务,例如 EF Core 数据库上下文。 通过构造函数参数提供需要这些服务(如 Razor Pages)的组件。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具会自动创建数据库上下文并将其注册到依赖项注入容器。 脚手架工具将以下高亮显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages()
   .WithStaticAssets();

app.Run();

用完成的示例进行故障排除

如果遇到无法解决的问题,请将你的代码与完成的项目进行比较。 查看或下载已完成的项目如何下载)。

后续步骤

在本教程中,添加了用于管理数据库中的电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

添加数据模型

  1. 解决方案资源管理器中,右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models;
    
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType] 属性,用于指定 ReleaseDate 属性中的数据类型。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而非时间信息。
  • string 后的问号表示该属性可为空。 有关详细信息,请参阅可为空引用类型

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

  1. 创建“Pages/Movies”文件夹

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  2. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

    新建分步引导项目

  3. 在“添加新脚手架”对话框中,选择Razor“使用 Entity Framework 的页面 (CRUD)”>,然后单击“添加”

    添加基架

  4. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
      2. 在“数据库提供程序”下拉列表中,选择“SQL Server”。
    3. 选择 并添加

    添加Razor页面

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

创建的文件将在下一教程中说明。

基架进程将以下突出显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages();

app.Run();

本教程稍后会解释 Program.cs 这些变更。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用的数据模型保持同步。 保存数据库中的现有数据。

在此部分中,程序包管理器控制台 (PMC) 窗口用于:

  • 添加初始迁移。

  • 使用初始迁移来更新数据库。

  • 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单

  • 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    
  • Add-Migration 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

将显示以下警告,该警告将在后面的步骤中解决:

实体类型“Movie”上没有为小数列“Price”指定类型。 如果值不符合默认精度和小数位数,值将被静默截断。 显式指定 SQL Server 列类型,该列类型可以容纳所有使用“HasColumnType()”的值。

  • 在 PMC 中,输入以下命令:

    Update-Database
    

    Update-Database 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,命令在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

数据上下文 RazorPagesMovieContext

  • 派生自 Microsoft.EntityFrameworkCore.DbContext
  • 指定数据模型中包含哪些实体。
  • 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。

生成的文件 Data/RazorPagesMovieContext.cs 中的 RazorPagesMovieContext 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; } = default!;
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 新建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  3. 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。 脚手架工具将以下高亮显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseRouting();

app.UseAuthorization();

app.MapStaticAssets();
app.MapRazorPages();

app.Run();

用完成的示例进行故障排除

如果遇到无法解决的问题,请将你的代码与完成的项目进行比较。 查看或下载已完成的项目如何下载)。

后续步骤

在本教程中,添加了用于管理数据库中的电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

添加数据模型

  1. 解决方案资源管理器中,右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models;
    
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType] 属性,用于指定 ReleaseDate 属性中的数据类型。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而非时间信息。
  • string 后的问号表示该属性可为 null。 有关详细信息,请参阅可为空引用类型

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

  1. 创建“Pages/Movies”文件夹

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  2. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

    新建分步引导项目

  3. 在“添加新脚手架”对话框中,选择Razor“使用 Entity Framework 的页面 (CRUD)”>,然后单击“添加”

    添加基架

  4. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
      2. 在“数据库提供程序”下拉列表中,选择“SQL Server”。
    3. 选择 并添加

    添加Razor页面

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

创建的文件将在下一教程中说明。

基架进程将以下突出显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

本教程稍后会解释 Program.cs 这些变更。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用的数据模型保持同步。 保存数据库中的现有数据。

在此部分中,程序包管理器控制台 (PMC) 窗口用于:

  • 添加初始迁移。

  • 使用初始迁移来更新数据库。

  • 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单

  • 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    
  • Add-Migration 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

将显示以下警告,该警告将在后面的步骤中解决:

实体类型“Movie”上没有为小数列“Price”指定类型。 如果值不符合默认精度和小数位数,值将被静默截断。 显式指定 SQL Server 列类型,该列类型可以容纳所有使用“HasColumnType()”的值。

  • 在 PMC 中,输入以下命令:

    Update-Database
    

    Update-Database 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,命令在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

数据上下文 RazorPagesMovieContext

  • 派生自 Microsoft.EntityFrameworkCore.DbContext
  • 指定数据模型中包含哪些实体。
  • 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; } = default!;
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 新建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  3. 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。 脚手架工具将以下高亮显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

用完成的示例进行故障排除

如果遇到无法解决的问题,请将你的代码与完成的项目进行比较。 查看或下载已完成的项目如何下载)。

后续步骤

在本教程中,添加了用于管理数据库中的电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

添加数据模型

  1. 解决方案资源管理器中,右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models;
    
    public class Movie
    {
        public int Id { get; set; }
        public string? Title { get; set; }
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string? Genre { get; set; }
        public decimal Price { get; set; }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType] 属性,用于指定 ReleaseDate 属性中的数据类型。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而非时间信息。
  • string 后的问号表示该属性可为空。 有关详细信息,请参阅可为空引用类型

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

  1. 创建“Pages/Movies”文件夹

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  2. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

    新建分步引导项目

  3. 在“添加新脚手架”对话框中,选择Razor“使用 Entity Framework 的页面 (CRUD)”>,然后单击“添加”

    添加基架

  4. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
      2. 在“数据库提供程序”下拉列表中,选择“SQL Server”。
    3. 选择 并添加

    添加Razor页面

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

创建的文件将在下一教程中说明。

基架进程将以下突出显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

本教程稍后会解释 Program.cs 这些变更。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用的数据模型保持同步。 保存数据库中的现有数据。

在此部分中,程序包管理器控制台 (PMC) 窗口用于:

  • 添加初始迁移。
  • 使用初始迁移来更新数据库。
  1. 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单

  2. 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    Update-Database
    
  • Add-Migration 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

  • Update-Database 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,命令在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

将显示以下警告,该警告将在后面的步骤中解决:

实体类型“Movie”上没有为小数列“Price”指定类型。 如果值不符合默认精度和小数位数,值将被静默截断。 显式指定 SQL Server 列类型,该列类型可以容纳所有使用“HasColumnType()”的值。

数据上下文 RazorPagesMovieContext

  • 派生自 Microsoft.EntityFrameworkCore.DbContext
  • 指定数据模型中包含哪些实体。
  • 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; } = default!;
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 新建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  3. 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。 脚手架工具将以下高亮显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

用完成的示例进行故障排除

如果遇到无法解决的问题,请将你的代码与完成的项目进行比较。 查看或下载已完成的项目如何下载)。

后续步骤

在本教程中,添加了用于管理数据库中的电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

添加数据模型

  1. 解决方案资源管理器中,右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models
    {
        public class Movie
        {
            public int ID { get; set; }
            public string Title { get; set; } = string.Empty;
    
            [DataType(DataType.Date)]
            public DateTime ReleaseDate { get; set; }
            public string Genre { get; set; } = string.Empty;
            public decimal Price { get; set; }
        }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType] 属性,用于指定 ReleaseDate 属性中的数据类型。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而非时间信息。

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

  1. 添加基架工具所需的 NuGet 包 Microsoft.EntityFrameworkCore.Design

    1. 工具 菜单中,选择 NuGet 包管理器>管理解决方案的 NuGet 包NuGet 包管理器 - 管理
    2. 选择“浏览”选项卡。
    3. 输入 Microsoft.EntityFrameworkCore.Design,然后从列表中选择它。
    4. 选中“项目”,然后选择“安装”
    5. 在“许可证接受”对话框中,选择“我接受” 。 NuGet 包管理器 - 添加包
  2. 创建“Pages/Movies”文件夹

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  3. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

    新建分步引导项目

  4. 在“添加新脚手架”对话框中,选择Razor“使用 Entity Framework 的页面 (CRUD)”>,然后单击“添加”

    添加基架

  5. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
    3. 选择 并添加

    添加Razor页面

    如果你看到一条错误消息,提示需要安装 Microsoft.EntityFrameworkCore.SqlServer 软件包,请从 添加>新建基架项目 开始重新执行这些步骤。

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

创建的文件将在下一教程中说明。

基架进程将以下突出显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

本教程稍后会解释 Program.cs 这些变更。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用的数据模型保持同步。 保存数据库中的现有数据。

在此部分中,程序包管理器控制台 (PMC) 窗口用于:

  • 添加初始迁移。
  • 使用初始迁移来更新数据库。
  1. 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单

  2. 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    Update-Database
    
    

上述命令安装 Entity Framework Core 工具,并运行 migrations 命令以生成可创建初始数据库架构的代码。

将显示以下警告,该警告将在后面的步骤中解决:

实体类型“Movie”上没有为小数列“Price”指定类型。 如果值不符合默认精度和小数位数,值将被静默截断。 显式指定 SQL Server 列类型,该列类型可以容纳所有使用“HasColumnType()”的值。

migrations 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

update 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,update 在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。 脚手架工具将以下高亮显示的代码添加到 Program.cs 文件中:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Data;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.MapRazorPages();

app.Run();

数据上下文 RazorPagesMovieContext

  • 派生自 Microsoft.EntityFrameworkCore.DbContext
  • 指定数据模型中包含哪些实体。
  • 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie>? Movie { get; set; }
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 新建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  3. 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

用完成的示例进行故障排除

如果遇到无法解决的问题,请将你的代码与完成的项目进行比较。 查看或下载已完成的项目如何下载)。

后续步骤

在本节中,添加了用于管理数据库中的电影的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。 首先要编写模型类,然后 EF Core 将创建数据库。

这些模型类被称为 POCO 类(源自“Plain-Old CLR Objects”),因为它们不依赖于 EF Core。 它们定义数据库中存储的数据属性。

查看或下载示例代码如何下载)。

添加数据模型

  1. 解决方案资源管理器中,右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

  2. 右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

  3. Movie 类添加以下属性:

    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace RazorPagesMovie.Models
    {
        public class Movie
        {
            public int ID { get; set; }
            public string Title { get; set; }
    
            [DataType(DataType.Date)]
            public DateTime ReleaseDate { get; set; }
            public string Genre { get; set; }
            public decimal Price { get; set; }
        }
    }
    

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType(DataType.Date)][DataType] 属性指定数据的类型 (Date)。 使用此属性:

    • 用户无需在日期字段中输入时间信息。
    • 仅显示日期,而非时间信息。

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

  1. 创建“Pages/Movies”文件夹:

    1. 右键单击Pages文件夹,然后选择>添加>新建文件夹
    2. 将文件夹命名为“Movies”。
  2. 右键单击 Pages/Movies 文件夹 >添加>新建基架项

    新建分步引导项目

  3. 在“添加基架”对话框中,选择 Razor“使用 Entity Framework 的 Pages (CRUD)”> 和“添加”。

    添加基架

  4. 完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

    1. 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
    2. 在“数据上下文类”行中,选择 +(加号)。
      1. 在“添加数据上下文”对话框中,生成类名
    3. 选择 并添加

    添加Razor页面

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

创建和更新的文件

在搭建基架时,会创建以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

更新的文件

  • Startup.cs

创建和更新的文件将在下一节中说明。

使用 EF 的迁移功能创建初始数据库架构

Entity Framework Core 中的迁移功能提供了一种方法来执行以下操作:

  • 创建初始数据库架构。
  • 以增量的方式更新数据库架构,使其与应用程序的数据模型保持同步。 保存数据库中的现有数据。

在此部分中,程序包管理器控制台 (PMC) 窗口用于:

  • 添加初始迁移。
  • 使用初始迁移来更新数据库。
  1. 在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

    PMC 菜单

  2. 在 PMC 中,输入以下命令:

    Add-Migration InitialCreate
    Update-Database
    

对于 SQL Server,前面的命令生成以下警告:“没有为实体类型“Movie”上的小数列“Price”指定类型”。 如果值不符合默认精度和小数位数,值将被静默截断。 使用“HasColumnType()”显式指定能够容纳所有值的 SQL Server 列类型。

忽略警告,因为它将在后面的步骤中得到解决。

migrations 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

update 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,update 在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。

检查 Startup.ConfigureServices 方法。 高亮显示的这一行是由脚手架工具添加的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
}

RazorPagesMovieContext 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。 数据上下文 (RazorPagesMovieContext) 派生自 Microsoft.EntityFrameworkCore.DbContext。 数据上下文指定数据模型中包含哪些实体。

using Microsoft.EntityFrameworkCore;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (
            DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; }
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  1. 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

    如果收到以下错误:

    SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
    Login failed for user 'User-name'.
    

    你漏掉了迁移步骤

  2. 测试 创建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  3. 测试“编辑”、“详细信息”和“删除”链接。

Entity Framework Core 中的 SQL 日志记录

日志配置通常由 Logging 文件的 appsettings.{Environment}.json 部分提供。 若要记录 SQL 语句,请将 "Microsoft.EntityFrameworkCore.Database.Command": "Information" 添加到 appsettings.Development.json 文件:

{
  "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": "*"
}

有了前面的 JSON,SQL 语句就会显示在命令行和 Visual Studio 输出窗口中。

有关详细信息,请参阅以下资源:

下一个教程将讲解通过脚手架生成的文件。

后续步骤

在本节中,会添加用于管理影片的类。 应用程序的模型类使用 Entity Framework Core (EF Core) 来处理数据库。 EF Core 是一种对象关系映射器 (O/RM),可简化数据访问。

模型类称为 POCO 类(源自“简单传统 CLR 对象”),因为它们与 EF Core 没有任何依赖关系。 它们定义数据库中存储的数据属性。

查看或下载示例代码如何下载)。

Warning

本文使用不需要对用户进行身份验证的本地数据库。 生产应用应使用可用的最安全的身份验证流。 有关已部署测试和生产应用的身份验证的详细信息,请参阅安全身份验证流

添加数据模型

右键单击“RazorPagesMovie”项目>“添加”>“新建文件夹”。 将文件夹命名为 Models

右键单击 Models 文件夹。 选择 添加>。 将类命名“Movie”。

Movie 类添加以下属性:

using System;
using System.ComponentModel.DataAnnotations;

namespace RazorPagesMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Movie 类包含:

  • 数据库需要 ID 字段以获取主键。

  • [DataType(DataType.Date)]DataType 属性指定数据的类型 (Date)。 使用此属性:

    • 用户无需在数据字段中输入时间信息。
    • 仅显示日期,而非时间信息。

DataAnnotations 会在后续教程中介绍。

DataAnnotations 会在后续教程中介绍。

生成项目以验证没有任何编译错误。

搭建“电影”模型的基架

在此部分,将搭建“电影”模型的基架。 也就是说,脚手架工具会为“电影”模型生成用于执行创建、读取、更新和删除 (CRUD) 操作的页面。

创建“Pages/Movies”文件夹:

  • 右键单击Pages文件夹,然后选择>添加>新建文件夹
  • 将文件夹命名为“Movies”。

右键单击 Pages/Movies 文件夹 >添加>新建基架项

VSCode 中新的脚手架项目

在“添加基架”对话框中,选择 Razor“使用 Entity Framework 的 Pages (CRUD)”> 和“添加”。

在 VScode 上添加基架

完成“使用 Entity Framework 添加Razor页面 (CRUD)”对话框:

  • 模型类下拉列表中,选择Movie (RazorPagesMovie.Models)
  • 数据上下文类行中,选择“+”(加号)并将生成的名称从 RazorPagesMovie.Models.RazorPagesMovieContext 更改为 RazorPagesMovie.Data.RazorPagesMovieContext。 不需要此更新。 它创建具有正确命名空间的数据库上下文类。
  • 选择 并添加

在 VS Code 中添加 Razor 页面

appsettings.json 文件通过用于连接到本地数据的连接字符串进行更新。

创建的文件

在搭建基架时,会创建并更新以下文件:

  • Pages/Movies:“创建”、“删除”、“详细信息”、“编辑”和“索引”。
  • Data/RazorPagesMovieContext.cs

Updated

  • Startup.cs

创建和更新的文件将在下一节中说明。

初始迁移

在此部分中,程序包管理器控制台 (PMC) 用于:

  • 添加初始迁移。
  • 使用初始迁移来更新数据库。

在“工具”菜单中,选择“NuGet 包管理器”“包管理器控制台”。

PMC 菜单

在 PMC 中,输入以下命令:

Add-Migration InitialCreate
Update-Database

前面的命令会生成以下警告:“未为实体类型“Movie”上的 decimal 列“Price”指定类型。” 如果值不符合默认精度和小数位数,值将被静默截断。 使用“HasColumnType()”显式指定能够容纳所有值的 SQL Server 列类型。

忽略警告,因为它将在后面的步骤中得到解决。

migrations 命令生成用于创建初始数据库架构的代码。 该架构基于在 DbContext 中指定的模型。 InitialCreate 参数用于为迁移命名。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。

update 命令在尚未应用的迁移中运行 Up 方法。 在这种情况下,update 在用于创建数据库的 Up 文件中运行 Migrations/<time-stamp>_InitialCreate.cs 方法。

检查通过依赖注入注册的上下文

ASP.NET Core 通过依赖关系注入进行生成。 在应用程序启动过程中通过依赖关系注入注册相关服务(例如 EF Core 数据库上下文)。 需要这些服务(如 Razor Pages)的组件通过构造函数参数提供。 本教程的后续部分介绍了用于获取数据库上下文实例的构造函数代码。

基架工具自动创建数据库上下文并将其注册到依赖关系注入容器。

检查 Startup.ConfigureServices 方法。 高亮显示的这一行是由脚手架工具添加的:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    services.AddDbContext<RazorPagesMovieContext>(options =>
      options.UseSqlServer(Configuration.GetConnectionString("RazorPagesMovieContext")));
}

RazorPagesMovieContext 为 EF Core 模型协调 Movie 功能,例如“创建”、“读取”、“更新”和“删除”。 数据上下文 (RazorPagesMovieContext) 派生自 Microsoft.EntityFrameworkCore.DbContext。 数据上下文指定数据模型中包含哪些实体。

using Microsoft.EntityFrameworkCore;

namespace RazorPagesMovie.Data
{
    public class RazorPagesMovieContext : DbContext
    {
        public RazorPagesMovieContext (
            DbContextOptions<RazorPagesMovieContext> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie.Models.Movie> Movie { get; set; }
    }
}

前面的代码为实体集创建 DbSet<Movie> 属性。 在实体框架术语中,实体集通常与数据表相对应。 一个实体对应于表中的一行。

通过调用 DbContextOptions 对象中的一个方法将连接字符串名称传递到上下文。 进行本地开发时,配置系统appsettings.json 文件中读取连接字符串。

测试应用

  • 运行应用并将 /Movies 追加到浏览器中的 URL (http://localhost:port/movies)。

如果您收到以下错误:

SqlException: Cannot open database "RazorPagesMovieContext-GUID" requested by the login. The login failed.
Login failed for user 'User-name'.

你漏掉了迁移步骤

  • 测试 创建 链接。

    “创建”页

    Note

    可能无法在 Price 字段中输入十进制逗号。 要支持 jQuery 验证在使用逗号(“,”)作为小数点的非英语语言环境中运行,并支持非美式英语日期格式,应用必须实现全球化。 有关全球化的说明,请参阅此 GitHub 问题

  • 测试“编辑”、“详细信息”和“删除”链接。

下一个教程将讲解通过脚手架生成的文件。

后续步骤