EF Core 遷移
感覺就是以前EF Code First的自動同步數據庫功能
內容:在你新增、更新TableModel后,如何自動化的更新DB中的真實Table。以及對這些更改進行一個版本控制。
本文將以一個示例進行簡單明了的演示輸出。(不會很詳細,只記錄主要步驟)
當下我們已經有了一個ASP.NET Core的web應用程序,本文我們所關心的只有2個:
1、Model
2、DB Table
當下:
Model
最后一個為導航屬性,無視。
Table
現在我們要在Model/Student.cs 加一個屬性
public string NewColForTest { get; set; }
更改后
對應的Table,我們希望變成如下
如何操作呢?
辦法有很多,本文介紹由EF Core提供的一種遷移。
優點
- 不需要去手動操作數據庫
- 不會影響現有db data(也就是不是重建db)
- 可追溯更改內容,即版本控制
開始動手
前期准備
建一個ASP.NET Core web Application,用EF Core連接好數據庫,建好Student.cs
編輯*.csproj 文件,添加highlight內容
cmd 定位到項目根目錄(即Startup.cs所在目錄)
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 已是最新,則無需運行遷移。
Now
更改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比較,運行的更加“透明”,讓我們更直接的知道發生了什么,黑魔法的感覺少了很多。Code First更新在配置完成下只需要運行F5,即DB 同步成功,讓人感覺不是那么“親近”。
認識較淺,請指教。
Thanks All.
歡迎討論~
感謝閱讀~
個人公眾號: