EntityFramework CodeFirst 4.3 step by step (3)
连续两天的博客平均访问量上千,给了我很大的鼓舞啊!今天继续讲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方面的东西了,先欠着园子里的朋友,以后还上!