EntityFramework CodeFirst 4.3 step by step (3)

连续两天的博客平均访问量上千,给了我很大的鼓舞啊!今天继续讲Migration。

首先我们来看一个需求,假设现在不允许Users表有重复的MyBlog,那我们怎么修改呢?

现在打开Migrations文件夹,看看下面多了些什么?仔细观察不难发现,多了一些以时间戳和昨天输入的命令字符串组成的类文件,

如201207181401353_AddUser.cs是用来创建User的,代码如下:

AddUser
 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. 打开该文件,看到如下代码:

AddIndex
 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这个约束,因此我们修改代码如下:

AddIndex
 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类,修改如下:

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方面的东西了,先欠着园子里的朋友,以后还上!

posted @ 2012-07-19 23:04  Evan Hua  阅读(2595)  评论(11编辑  收藏  举报