官方说法是:设定数据库种子https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/sql

应用背景:初次部署系统时,设定一些默认的数据,比如后台管理员初始账号等信息。

在 Models 文件夹中创建一个名为 SeedData 的新类。 将生成的代码替换为以下代码:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new MovieContext(
                serviceProvider.GetRequiredService<DbContextOptions<MovieContext>>()))
            {
                // 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();
            }
        }
    }
}

如果 DB 中没有任何电影,则会返回种子初始值设定项,并且不会添加任何电影。(不是很理解该翻译,个人理解是:如果数据表中存在记录,则返回,不会将初始化数据写入数据表中。)

if (context.Movie.Any())
{
    return;   // DB has been seeded.
}

添加种子初始值设定项

将种子初始值设定项添加 Program.cs 文件中的 Main 方法末端:

// Unused usings removed.
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RazorPagesMovie.Models;
using System;
using Microsoft.EntityFrameworkCore;

namespace RazorPagesMovie
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = BuildWebHost(args);//初始化数据库开始

            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;

                try
                {
                    var context = services.GetRequiredService<MovieContext>();
                    // requires using Microsoft.EntityFrameworkCore;
                    context.Database.Migrate();
                    // Requires using RazorPagesMovie.Models;
                    SeedData.Initialize(services);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred seeding the DB.初始化数据库时发生错误!");
                }
            }//初始化数据库结束

            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

测试应用


  • 删除 DB 中的所有记录。 可以使用浏览器中的删除链接,也可以从 SSOX 执行此操作
  • 强制应用初始化(调用 Startup 类中的方法),使种子方法能够正常运行。 若要强制进行初始化,必须先停止 IIS Express,然后再重新启动它。 可以使用以下任一方法来执行此操作:

    • 右键单击通知区域中的 IIS Express 系统任务栏图标,然后点击“退出”或“停止站点”:

  • 如果是在非调试模式下运行 VS 的,请按 F5 以在调试模式下运行。
  • 如果是在调试模式下运行 VS 的,请停止调试程序并按 F5。

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

 

但是这里存在另外一个问题:如果一部分数据库数据表中已经存在数据了,现在又想初始化另外的数据表怎么办?

改造一下
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
                        }
                    );
                }
                if (!context.Class.Any())
                {
                    //return;

                    context.Class.AddRange(
                        new Class
                        {
                            Name = "国产电影",
                            bz = "国产电影备注"
                        },
                        new Class
                        {
                            Name = "日韩电影",
                            bz = "日韩电影备注"
                        });
                }
                context.SaveChanges();

测试:删掉任意一个数据库中的数据,然后重启,原本存在数据的数据表不会有改动,没有数据的数据表将写入默认数据。