Entity Framework Core 中的种子数据

admin
admin
2021-06-03
分享:

本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP)
本文出自《从零开始学 ASP.NET Core 与 EntityFramework Core》目录
视频课程效果更佳:跨平台开发实战掌握 ASP.NET Core 与 EntityFramework Core

Entity Framework Core 中的种子数据

在传统的 Ado.net 开发方式中,我们都是使用 sql 文件来进行创建数据库,创建好了之后再执行一个装满了初始化数据的 sql 文件,这样的文件我们随时都要去手动维护它,如果版本控制的不好,还有可能造成数据的丢失和遗漏,给我们的项目和客户造成很大的麻烦。

而 EF Core 帮我们解决了这个问题, 本章节,我们将学习如何使用 Entity Framework Core 中的迁移功能为数据库中的表添加初始数据。而这些数据可以称作为:种子数据

您如果使用的是 Entity Framework Core 2.1 或更高版本,则可以使用一种新方法来为数据库添加这些种子数据,这个过程我们可以叫做播种。如果低于这个版本,请升级您的项目中的 EF Core。

如何启用种子数据

在我们的应用程序 DbContext 类中,重写 OnModelCreating()方法。在这个例子中,使用 HasData()方法为 Student 实体播种数据。

  public class AppDbContext:DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options):base(options)
        {
        }

        public DbSet<Student> Students { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().HasData(
                new Student
                {
                    Id = 1,
                    Name = "梁桐铭",
                    Major = MajorEnum.FirstGrade,
                    Email = "ltm@ddxc.org"
                }
            );
        }
    }

将种子数据添加到表中

首先我们要添加一个新的迁移记录,参考以下代码。我将迁移一个命名为SeedStudentsTable的迁移记录,指定它将种子数据添加到Student数据库表中。

Add-Migration SeedStudentsTable

上述命令生成以下代码:

  public partial class SeedStudentsTable : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.InsertData(
                table: "Students",
                columns: new[] { "Id", "Major", "Email", "Name" },
                values: new object[] { 1, 1, "ltm@ddxc.org", "梁桐铭" });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DeleteData(
                table: "Students",
                keyColumn: "Id",
                keyValue: 1);
        }
    }

然后我们执行Update-Database命令,将迁移记录应用到数据库中。

更改现有的数据库种子数据

您可以通过更改现有种子数据或者添加另一个新迁移来更新种子数据。

第一步:修改**OnModelCreating()**的方法

     protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().HasData(
                new Student
                {
                    Id = 1,
                    Name = "52ABP管理员",
                    Major = MajorEnum.FirstGrade,
                    Email = "info@ddxc.org"
                },
                  new Student
                  {
                      Id = 2,
                      Name = "角落的白板报",
                      Major = MajorEnum.GradeThree,
                      Email = "werltm@qq.com"
                  }
            );
        }

第二步:添加一个新迁移记录


Add-Migration AlterStudentsSeedData

第三步:将新生成的迁移记录添加到数据库中

Update-Database

保持 DbContext 类的干净

目前我们添加了种子数据,目前数据还比较少,但是随着业务的扩大和发展,数据也会随着变多。这样会让 Dbcontext 类变得臃肿,可读性差,而且不利于解耦。所以我们要让 Dbcontext 类保持干净。

为了保持 DbContext 类的干净,我们可以将种子设定代码从 DbContext 类移动到 ModelBuilder 类上的扩展方法中。

我们在 Models 文件夹中创建一个 ModelBuilderExtensions.cs 文件,添加如下代码:

 public static class ModelBuilderExtensions
    {
        public static void Seed(this ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().HasData(
                 new Student
                 {
                     Id = 1,
                     Name = "52ABP管理员",
                     Major = MajorEnum.FirstGrade,
                     Email = "info@ddxc.org"
                 },
                   new Student
                   {
                       Id = 2,
                       Name = "角落的白板报",
                       Major = MajorEnum.GradeThree,
                       Email = "werltm@qq.com"
                   }
             );
        }
    }

请注意: 这个方法必须是静态方法。因为扩展方法只能在静态类中定义。

我们打开在 DbContext 类中**OnModelCreating()**方法,只需要在下面添加一行代码


protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Seed();
}

让它去执行我们所写的 ModelBuilder 的扩展方法Seed(),这样无论我们的业务变得有复杂,我们都只需要去维护**Seed()**方法即可,无须去频繁改动 DbContext,而且我们的实体发生变动的时候,智能提示还是编译失败,以此来告诉我们,需要更新种子数据。

文章说明

如果您觉得我的文章质量还不错,欢迎打赏,也可以订阅我的视频哦
未得到授权不得擅自转载本文内容,52abp.com 保留版权
感谢您对我的支持

关注微信公众号:角落的白板报

公众号:角落的白板报