首页>教程>ASP.NET Core7.0教程>ASP.NET Core 中 Razor 页面使用数据库

ASP.NET Core 中 Razor 页面使用数据库

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) 。

右键单击 Movie 表,然后选择“视图设计器”:

请注意 ID 旁边的密钥图标。 默认情况下,EF 为该主键创建一个名为 ID 的属性。

右键单击 Movie 表,然后选择“查看数据”:

Visual Studio Code / Visual Studio for Mac

SQLite

SQLite 网站上表示:

SQLite 是一个自包含、高可靠性、嵌入式、功能完整、公共域的 SQL 数据库引擎。 SQLite 是世界上使用最多的数据库引擎。

可以下载许多第三方工具来管理并查看 SQLite 数据库。 下面的图片来自 DB Browser for SQLite。 如果你有最喜欢的 SQLite 工具,请发表评论以分享你喜欢的方面。

备注

在本教程中,使用 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()) 上放置断点并单步执行代码。

应用将显示设定为种子的数据:

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索