連續兩天的博客平均訪問量上千,給了我很大的鼓舞啊!今天繼續講Migration。
首先我們來看一個需求,假設現在不允許Users表有重復的MyBlog,那我們怎么修改呢?
現在打開Migrations文件夾,看看下面多了些什么?仔細觀察不難發現,多了一些以時間戳和昨天輸入的命令字符串組成的類文件,
如201207181401353_AddUser.cs是用來創建User的,代碼如下:

1 public partial class AddUser : DbMigration 2 { 3 public override void Up() 4 { 5 CreateTable( 6 "Users", 7 c => new 8 { 9 UserId = c.Int(nullable: false, identity: true), 10 UserName = c.String(), 11 MyBlog = c.String(), 12 }) 13 .PrimaryKey(t => t.UserId).Index(t => t.UserName, unique: true); 14 } 15 16 public override void Down() 17 { 18 DropTable("Users"); 19 } 20 }
我們發現這個Up方法里面實際上就是創建表的,而我們的需求中不允許有重復的MyBlog值,其實就是創建一個Unique的約束,方法如下:
1. 既然Migrations文件夾中的類可以用來修改數據庫,那不管怎樣咱得整一個出來啊,在Package Manager Console中輸入“Add-Migration AddIndex ”命令然后回車,然后到Migrations文件夾中看下果然多了一個201207191412098_AddIndex.cs類文件。
2. 打開該文件,看到如下代碼:

1 public partial class AddIndex : DbMigration 2 { 3 public override void Up() 4 { 5 6 } 7 8 public override void Down() 9 { 10 11 } 12 }
根據AddUser類中的內容依樣畫葫蘆,我們肯定是在Up()方法中增加這個約束,在Down()方法中Drop這個約束,因此我們修改代碼如下:

1 public partial class AddIndex : DbMigration 2 { 3 public override void Up() 4 { 5 CreateIndex("Users", "MyBlog", unique: true); 6 } 7 8 public override void Down() 9 { 10 DropIndex("Users", "MyBlog"); 11 } 12 }
3. 然后我們在Package Manager Console中輸入“update-database -verbose”命令然后回車,大功告成!
注:前提是數據庫中不能存在已經重復的數據,不然會禁止創建該約束的!
下面介紹一個比較直截了當的功能,Migration中執行Sql語句直接改數據庫,這招可是包治百病啊!
假設我們要把MyBlog的值前面都加上User的Id,我們用執行Sql語句的方法可以這樣實現:
1. Package Manager Console中輸入"Add-Migration SetValueOfMyBlog"命令然后回車
2. 找到生成的SetValueOfMyBlog類,修改如下:

1 public partial class SetValueOfMyBlog : DbMigration 2 { 3 public override void Up() 4 { 5 Sql("update Users set MyBlog=str(UserId)+'www.cnblogs'"); 6 } 7 8 public override void Down() 9 { 10 } 11 }
3. Package Manager Console中輸入"update-database -verbose"命令然后回車,搞定!
注意:每個Migration類文件只能用update-database -verbose命令執行一次,下次update-database -verbose命令執行的時候不會執行已經執行過的Migration類文件,即使你修改了它。
CodeFirst還可以將數據庫可以恢復到某一個版本,如果我們想將revert剛才的Add-Migration SetValueOfMyBlog,我們需要使用‘Update-Database –TargetMigration:"SetValueOfMyBlog"命令,不難發現這個Migration的過程其實就是一個入棧和彈棧的過程,棧中元素就是這一個個Migration類文件。
嘿,哥們,裝ReSharper了嗎?裝的話F12一下DbMigration類進去看看吧,究竟Migration能做多少事情,一下DbMigration類的源碼就知道了,我唯一覺得有點反感的是里面居然沒有注釋,頓時就不想看下去,我承認它的很多方法名字都取的很好,但是方法參數總要解釋一下的吧。。。這要在我們公司StyleCopy是run不過去的,代碼就不能check in(不得不說德國人做事情真是細致入微啊)。。。突然又想寫一寫Clean Code方面的東西了,先欠着園子里的朋友,以后還上!