EF Core Model更新迁移

在.net 开发中,如你的项目中使用EF进行数据管理,当需要新增、修改EF Model结构时,怎样才能自动化的更新DB中的真实Table。以及对这些更改进行一个版本控制。

下面我将使用一个ASP.NET Core的web应用程序,来演示该操作:
1、Model


2、DB Table

 

假设现在我们要在Model/Student.cs 加一个属性

 public string NewColForTest { get; set; }

  新的模型变为:

对应的Table,我们希望变成如下

操作步骤:

建一个ASP.NET Core web Application,用EF Core连接好数据库,建好Student.cs

编辑*.csproj 文件,添加highlight内容

 

cmd 定位到项目根目录并执行以下语句

dotnet ef migrations add InitialCreate

  

将初始化EF Core用于迁移的文件。InitialCreate是其中一个迁移记录的版本文件名,暂不关心。

现在你的项目中将多出:

【SchoolContext】ModelSnapshot里面记录了要生成db的内容。

20180513071210_【InitialCreate】记录了此次更新(同上个版本)的部分,由于我们是第一次初始化,所以里面记录了全部表结构内容。

【SchoolContext】ModelSnapshot:

partial class SchoolContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        { 
            modelBuilder
                .HasAnnotation("ProductVersion", "2.0.2-rtm-10011")
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

           ...

            modelBuilder.Entity("ContosoUniversity.Models.Student", b =>
                {
                    b.Property<int>("ID")
                        .ValueGeneratedOnAdd();

                    b.Property<DateTime>("EnrollmentDate");

                    b.Property<string>("FirstMidName");

                    b.Property<string>("LastName");

                    b.Property<string>("NewColForTest");

                    b.HasKey("ID");

                    b.ToTable("Student");
                });

            ...
        }
    }

  20180513071210_【InitialCreate】:

public partial class InitialCreate : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            ...

            migrationBuilder.CreateTable(
                name: "Student",
                columns: table => new
                {
                    ID = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    EnrollmentDate = table.Column<DateTime>(nullable: false),
                    FirstMidName = table.Column<string>(nullable: true),
                    LastName = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Student", x => x.ID);
                });

           ... 
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            ...
            migrationBuilder.DropTable(
                name: "Student");
        }
    }

  回到cmd 定位到项目根目录执行

dotnet ef database update

EF Core将为我们跟db同步

现在我们的db应该跟Model是一致的(多余的细节,这里就不赘述了)

做到这里,我们应该清楚EF Core是通过生成/Migrations Folder的内容来实现同步db。

此时还会新生成一个表用于版本记录

EF Core 使用 __MigrationsHistory 表查看是否需要运行任何迁移。 如果 DB 已是最新,则无需运行迁移。

现在开始更改Student.cs

添加新属性NewColForTest

按照我们的猜测,要同步更新db,应该就是更改/Migrations Folder里的内容。把该属性对应的添加上去,然后执行

dotnet ef database update

  

即可实现同步更新(迁移)。

现在这里可以手动更改/Migrations Folder里的两个文件,然后执行cmd。

那么可以不手动吗?

可以,先执行命令,生成一个新的差异版本Migration,我们命名为UpdateStudent

dotnet ef migrations add UpdateStudent

执行结果:

点开文件

只有差异内容。

 public partial class UpdateStudent : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<string>(
                name: "NewColForTest",
                table: "Student",
                nullable: true);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "NewColForTest",
                table: "Student");
        }
    }

  最后执行

dotnet ef database update

  

查看db

原有的数据也仍在。完成。

注意:如果命令报错,可以检查是否把iis express退出。

总结:

我觉得很大一个亮点是每次更新都生成一个追踪版本,某些情况下,省去了单独维护sql 脚本的工作。

与EF Code First比较,运行的更加“透明”,让我们更直接的知道发生了什么

 

posted @ 2019-04-17 16:13  e天下小熊  阅读(449)  评论(0编辑  收藏  举报