使用CodeFirst创建并更新数据库

发表于:2016-7-14 10:07

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:雪飞鸿    来源:51Testing软件测试网采编

  2. 更新数据库(Code Fist Migration)
  现在,我们给Author类增加字属性Email,代码如下:
  [Table("T_Authors")]
  public class Author
  {
  public int Id { set; get; }
  public string Name { set; get; }
  public string Email { set; get; }
  public virtual ICollection<Blog> Blogs { set; get; }
  }
  此时,再次运行该应用程序,则将抛出异常
  An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
  The model backing the 'MyDbContext' context has changed since the database was created. Consider using Code First Migrations to
  update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
  异常信息中提示我们数据库创建之后model发生了变化,所以我们需要对数据库进行更新使二者保持一致才能运行程序。
  2.1 启用迁移
  对于首次迁移需要启用迁移,具体方法是在Packge Manager Console中输入Enable-Migrations命令即可。
  命令运行完毕之后我们会看到命令行中的提示信息
  这里我们只是启用了迁移,但不是自动迁移。从提示信息中我们可以看到若要启用自动迁移则要删除Migrations文件夹并在Packge Manager Console中输入
  Enable-Migrations –EnableAutomaticMigrations命令或者在Migrations文件夹的Configuration.cs文件中设置AutomaticMigrationsEnabled属性为true即可。
  Enable-Migrations命令运行完毕之后会在项目中生成如下文件:
  Configuration文件 我们可以在此文件中针对上下文配置迁移行为。
  InitialCreate文件   因为我们事先让 Code First 自动创建了一个数据库,这个迁移文件中的代码表示数据库中已创建的对象。该文件文件名包含时间戳,这对于排序十分有帮助。如果尚未创建数据库,则不会将此 InitialCreate 迁移添加到项目中。而是,首次调用 Add-Migration 时,用于创建这些表的代码将为新迁移搭建基架。
  2.2 更新数据库
  启用迁移之后,在Packge Manager Console中继续输入Update-Database命令来更新数据库,但会发现更新失败。
  通过上面的提示信息我们可以知道,要想更新数据库需要启用自动迁移或者使用Add-Migration命令来创建迁移文件。
  2.2.1 基于代码的迁移
  我们在Packge Manager Console中输入命令Add-Migration AddEmail,命令运行完毕后我们会发现Migrations文件夹下已经创建了_AddEmail文件,文件内容如下:
1 public partial class AddEmail : DbMigration
2 {
3     public override void Up()
4     {
5         //注意,这里数据表的名称是dbo.T_Blogs和dbo.T_Authors而不是我们指定的
6         //T_Blogs和T_Authors,我们可以把数据表名称改为T_Blogs和T_Authors
7         //数据表以dbo开头貌似是SQL SERVER中的命名方式,这里小编使用的是MYSQL
8         CreateTable(
9             "dbo.T_Blogs",
10             c => new
11                 {
12                     Id = c.Int(nullable: false, identity: true),
13                     Author_Id = c.Int(),
14                 })
15             .PrimaryKey(t => t.Id)
16             .ForeignKey("dbo.T_Authors", t => t.Author_Id)
17             .Index(t => t.Author_Id);
18
19         AddColumn("dbo.T_Authors", "Email", c => c.String(unicode: false));
20     }
21
22     public override void Down()
23     {
24         DropForeignKey("dbo.T_Blogs", "Author_Id", "dbo.T_Authors");
25         DropIndex("dbo.T_Blogs", new[] { "Author_Id" });
26         DropColumn("dbo.T_Authors", "Email");
27         DropTable("dbo.T_Blogs");
28     }
29 }
30
  我们可以看到Up方法中调用了AddColumn方法来向数据库中添加Email字段。这时我们在Packge Manager Console中输入命令Update-Database命令(也可以使用Update-Database -Verbose命令,该命令可以使我们看到SQL语句的执行过程,注意-Verbose和-Database之间有个空格)并运行,可以看到命令成功执行,然后到数据库中查看数据表T_Authors发现表中已经添加字段Email,同时数据表__migrationhistory中对于我们的此次更新进行了记录。
  对于上述代码我们可以进行简化:
public partial class AddEmail : DbMigration
{
public override void Up()
{
AddColumn("T_Authors", "Email", c => c.String(unicode: false));
}
public override void Down()
{
DropColumn("T_Authors", "Email");
}
}
  我们也可以直接通过创建迁移文件来更新数据库而不修改Model。如:
  通过命令Add-Migration addAge来创建一个新的迁移文件,代码如下:
public partial class AddAge : DbMigration
{
public override void Up()
{
AddColumn("T_Authors", "Age", c => c.Int(nullable: false,defaultValue:18));
}
public override void Down()
{
DropColumn("T_Authors", "Age");
}
}
  然后运行命令Update-Database,我们会发现数据库T_Authors表中创建了字段Age。虽然成功的更新了数据库,但会导致程序中的Model和数据表不匹配。
  2.2.2  自动迁移
  启用自动迁移的方法前文已经陈述。在启用自动迁移之后,我们再修改Model文件,只需执行Update-Database命令即可完成对数据库的更新。
  最后再补充一点,在创建数据库之后若修改TableAttribute和ColumnAttribute的值,那么在执行程序时EF会按照TabelAttribute和ColumnAttribute中指定的值和数据库进行匹配,但数据库中并不存在我们新指定的数据表和字段,这会导致程序报错。若我们修改了TableAttribute和ColumnAttribute的值,然后再使用Update-Database命令来更新数据库,数据库会新建一张有TableAttribute指定名称的数据表。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号