本文內容:
1,學習Entity Framework Code First 遷移功能(Migrations)
2,更新Model Class(Model Class中添加新的字段),然后把更新應用於datebase.
默認情況下,就像我們之前用Models下的movie.cs右鍵點擊直接添加database的時候,Code First自動在數據庫中添加新的表來記錄新添加的database時候和movie.cs同步,如果不同步,Entity Framework就會跑出錯誤。這樣我們就可以在開發的過程中發現錯誤,而不是必須在運行的時候才發現錯誤。
一,為Model的改變設置Code First Migrations功能(Setting up Code First Migrations for Model Changes),從而可以讓movie.cs改變的時候,把改變應用於Database(Model類和自動生成的數據庫同步)
1,1刪除MovieDBContext,刪除.mdf文件

1.2Ctrl+Shift+B重建解決方案后,打開“套件管理器控制台”:

PM>提示符后面執行Enable-Migrations命令開啟Code First Migrations功能,我們現在直接輸入:Enable-Migrations,可以看到提示命令:
我們需要Enable的是Movie,直接Copy提示命令中的下面的一行命令:
Enable-Migrations -ContextTypeName MvcMovie.Models.MovieDBContext
開啟成功:

解決方案下創建了Migrations文件夾:

1.3,更改Configuration.cs中的寫Seed方法,打開Configuration.cs,我們看到
{
// 這個方法將會在Migrations后被調用
// This method will be called after migrating to the latest version.
// 你可以用DbSet<T>的.AddOrUpdate擴展方法,避免創建重復的數據
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
更新Seed方法:
{
context.Movies.AddOrUpdate( i => i.Title,
new Movie
{
Title = " When Harry Met Sally ",
ReleaseDate = DateTime.Parse( " 1989-1-11 "),
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
}
);
}
添加引用:

Code First Migrations 在每一次migration之后都會調用這個Seed方法,從而更新Database中的數據(Insert orUpdate)
1,4重建解決方案。為Migrations創建一個新的DbMigration.cs類繼承自DbMigration,這一步將會新建一個Database,這就是我們之前要刪除movie.mdf的原因.
在Package Manager Console中執行命令:add-migration Initial 生成 intial migration. “intial”是任意命名的,用來命名創建的migration文件。這個類是用來創建新的數據庫

Code First 創建了一個帶有時間戳的_Initial.cs,這個類中的代碼實現了創建數據庫表,當你更新類中的表的時候,_Initial.cs將會運行更新dabatbase中的表,然后Seed方法填充測試數據到Database的Table中。這些遷移文件類文件都是以時間戳為前綴命名並排序的:

{
public override void Up()
{
CreateTable(
" dbo.Movies ",
c => new
{
ID = c.Int(nullable: false, identity: true),
Title = c.String(),
ReleaseDate = c.DateTime(nullable: false),
Genre = c.String(),
Price = c.Decimal(nullable: false, precision: 18, scale: 2),
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropTable( " dbo.Movies ");
}
}
現在我們運行命令PM>update-datebase 來創建數據庫,運行Seed方法:

如果運行update-database方法的時提示Table已經存在,是因為你在刪除表之后運行了項目。如果是這樣再次把Movie.mdf刪除,然后執行update-datebase命令。如果還是報錯,刪除Migrations文件夾,然后從上面刪除Movie.mdf處重新按照本文介紹的一步一步來。
Ctrl+F5執行程式,我們看到了Seed方法中的數據:

二,在Movie Model中添加新的屬性字段,把字段同步到DB的Table中
{
// Moive 類就相當於數據庫中的一張名為Movie的Table
// Movie 類實例化的對象相當於Table中的一行,實例的各個屬性(ID,Title...)相當於Table中的列
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}
// MovieDBContext class ,繼承自Entity Framework中的DbContext,代表這Movie數據上下文
// MovieDBContext class ,讀取、存儲、更新Movie Class 實例
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
}
Ctrl+Shift+B重建解決方案,然后在View中的各個頁面添加Rating屬性:

@Html.LabelFor(model => model.Rating)
</div>
<div class= " editor-field ">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
Ctrl+F5運行程序,提示如下:

這是因為我們剛剛在Model中的Movie.cs中添加了新的屬性字段,Movie.cs中的字段和已經存在的Database中的表字段不一致:

我們用Code First Migrations來解決這個問題:
1,在Seed中的每一個對象實例中添加 Rating= "G",如:
new Movie
{
Title = " When Harry Met Sally ",
ReleaseDate = DateTime.Parse( " 1989-1-11 "),
Genre = " Romantic Comedy ",
Rating = " G ",
Price = 7.99M
},
2,執行以下命令PM>add-migration AddRatingMig
這個命令告訴migration framework 檢查當前的movie model是否和dabatase 中的Movie 字段一致,如果不一致,就會添加必要的code來更新DB和新的Model一致:


3,解決方案下面新建了帶有時間戳的_AddRatingMig.cs文件,文件中有添加和刪除新的列,保證Model和DB
中的字段一致
{
using System;
using System.Data.Entity.Migrations;
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn( " dbo.Movies ", " Rating ", c => c.String());
}
public override void Down()
{
DropColumn( " dbo.Movies ", " Rating ");
}
}
}
4,執行命令PM>update-database
5,刷新”MovieDBContext”后我們看到在Movie.cs中添加的屬性同步到了DB的Table中:

Migrations Configuration.cs中的Sample數據也填充到了Database中:

6,Ctrl+Shift+B,Ctrl+F5運行,我們看到所有的頁面中都有了Rating:


這一節,我們可以在Model中添加新的屬性,並且同步到DB中。我們也學習了,把Sample數據填充到DB的Table中。下一節,我們將會在Model Class中對新增數據添加邏輯驗證(validation logic)和業務規則(business rules).
See You。。。
