RazorPagesMovieContext
对象处理连接到数据库并将 Movie
对象映射到数据库记录的任务。 向中的依赖关系注入容器注册数据库上下文:
Visual Studio
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();
Visual Studio Code / Visual Studio for Mac
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));
ASP.NET Core 配置系统会读取 键。 进行本地开发时,配置从 appsettings.json
文件获取连接字符串。
Visual Studio
生成的连接字符串类似于以下 JSON:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"RazorPagesMovieContext": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesMovieContext-bc;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Visual Studio Code / Visual Studio for Mac
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"RazorPagesMovieContext": "Data Source=MvcMovie.db"
}
}
将应用部署到测试或生产服务器时,可以使用环境变量将连接字符串设置为测试或生产数据库服务器。
Visual Studio
SQL Server Express LocalDB
LocalDB 是轻型版的 SQL Server Express 数据库引擎,以程序开发为目标。 LocalDB 作为按需启动并在用户模式下运行的轻量级数据库没有复杂的配置。 默认情况下,LocalDB 数据库在 C:\Users\<user>\
目录下创建 *.mdf
文件。
从“视图”菜单中,打开“SQL Server 对象资源管理器”(SSOX) 。
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043349939.png)
右键单击 Movie
表,然后选择“视图设计器”:
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043340558.png)
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043318774.png)
请注意 ID
旁边的密钥图标。 默认情况下,EF 为该主键创建一个名为 ID
的属性。
右键单击 Movie
表,然后选择“查看数据”:
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043305333.png)
Visual Studio Code / Visual Studio for Mac
SQLite
SQLite 网站上表示:
SQLite 是一个自包含、高可靠性、嵌入式、功能完整、公共域的 SQL 数据库引擎。 SQLite 是世界上使用最多的数据库引擎。
可以下载许多第三方工具来管理并查看 SQLite 数据库。 下面的图片来自 DB Browser for SQLite。 如果你有最喜欢的 SQLite 工具,请发表评论以分享你喜欢的方面。
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043437407.png)
备注
在本教程中,使用 Entity Framework Core 迁移功能(若可行)。 迁移会更新数据库架构,使其与数据模型中的更改相匹配。 但是,迁移仅能执行 EF Core 提供程序所支持的更改类型,且 SQLite 提供程序的功能将受限。 例如,支持添加列,但不支持删除或更改列。 如果已创建迁移以删除或更改列,则 ef migrations add
命令将成功,但 ef database update
命令会失败。 由于上述限制,本教程不对 SQLite 架构更改使用迁移。 转而在架构更改时,放弃并重新创建数据库。
要绕开 SQLite 限制,可手动写入迁移代码,在表内容更改时重新生成表。 表重新生成涉及:
- 创建新表。
- 将旧表中的数据复制到新表中。
- 放弃旧表。
- 为新表重命名。
设定数据库种子
使用以下代码在 Models 文件夹中创建一个名为 SeedData
的新类:
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
namespace RazorPagesMovie.Models
{
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new RazorPagesMovieContext(
serviceProvider.GetRequiredService<
DbContextOptions<RazorPagesMovieContext>>()))
{
if (context == null || context.Movie == null)
{
throw new ArgumentNullException("Null RazorPagesMovieContext");
}
// 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();
}
}
}
}
如果数据库中有任何电影,则会返回种子初始值设定项,并且不会添加任何电影。
if (context.Movie.Any())
{
return;
}
添加种子初始值设定项
使用下面突出显示的代码更新 Program.cs
:
Visual Studio
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;
var builder = WebApplication.CreateBuilder(args);
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();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Visual Studio Code / Visual Studio for Mac
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Data;
using RazorPagesMovie.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<RazorPagesMovieContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("RazorPagesMovieContext") ?? throw new InvalidOperationException("Connection string 'RazorPagesMovieContext' not found.")));
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
在上述代码中,修改了 Program.cs
来执行以下操作:
- 从依赖注入 (DI) 容器中获取数据库上下文实例。
- 调用
seedData.Initialize
方法,并向其传递数据库上下文实例。 - Seed 方法完成时释放上下文。 using 语句将确保释放上下文。
未运行 Update-Database
时出现以下异常:
SqlException: Cannot open database "RazorPagesMovieContext-" requested by the login. The login failed.
Login failed for user 'user name'.
测试应用
删除数据库中的所有记录,使种子方法运行。 停止并启动应用以设定数据库种子。 如果数据库未设定种子,请在 if (context.Movie.Any())
上放置断点并单步执行代码。
应用将显示设定为种子的数据:
![](https://cfiles.51aspx.com/wp-content/uploads/2022/08/20220812043613138.png)