第十七节: EF的CodeFirst模式的四种初始化策略和通过Migration进行数据的迁移
一. 四种初始化策略
EF的CodeFirst模式下数据库的初始化有四种策略:
1. CreateDatabaseIfNotExists:EF的默认策略,数据库不存在,生成数据库;一旦model发生变化,抛异常,提示走数据迁移
2. DropCreateDatabaseIfModelChanges:一旦model发生变化,删除数据库重新生成
3. DropCreateDatabaseAlways:数据库每次都重新生成
4. 自定义初始化(继承上面的三种策略中任何一种,然后追加自己的业务)
关闭数据库初始化策略:
Database.SetInitializer<dbContext6>(null); (改变实体类,不会报错,不会丢失数据,但无法映射改变数据库结构了)
代码如下:
public class dbContext6 : DbContext { public dbContext6() : base("name=dbContext6") { //在这里可以改变生成数据库的初始化策略 //1. CreateDatabaseIfNotExists (EF的默认策略,数据库不存在,生成数据库;一旦model发生变化,抛异常,提示走数据迁移) //Database.SetInitializer<dbContext6>(new CreateDatabaseIfNotExists<dbContext6>()); //2. DropCreateDatabaseIfModelChanges (一旦model发生变化,删除数据库重新生成) //Database.SetInitializer<dbContext6>(new DropCreateDatabaseIfModelChanges<dbContext6>()); //3.DropCreateDatabaseAlways (数据库每次都重新生成) //Database.SetInitializer<dbContext6>(new DropCreateDatabaseAlways<dbContext6>()); //4. 自定义初始化(继承上面的三种策略中任何一种,然后追加自己的业务) //Database.SetInitializer<dbContext6>(new MySpecialIntializer()); //5. 禁用数据库策略(不会报错,不会丢失数据,但是改变不了数据库的结构了) //Database.SetInitializer<dbContext6>(null); } public DbSet<Animal> Animal { get; set; } public DbSet<AnimalKind> AnimalKind { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } /// <summary> /// 自定义一个初始化策略,每次初始化时追加10条数据 /// </summary> public class MySpecialIntializer : DropCreateDatabaseAlways<dbContext6> { public override void InitializeDatabase(dbContext6 context) { base.InitializeDatabase(context); } //重写seed,追加初始数据 protected override void Seed(dbContext6 context) { for (int i = 0; i < 10; i++) { context.Animal.Add(new Animal() { id = "animal" + i, animalName = "mru" + i, animalKind = "mruru" + i, }); } context.SaveChanges(); base.Seed(context); } } }
总结:以上四种初始化策略,让我们知道了上一个章节中,为什么数据库结构发生变化就会抛异常,但是无论哪种方式,还是没有解决数据丢失的问题,解决数据丢失问题,详见:数据迁移。
二. 数据迁移(代码的形式非指令)
数据迁移很好的解决了修改表结构,数据丢失的问题,在本章节介绍通过代码的形式处理数据迁移问题,指令控制的形式,在后面章节介绍。
步骤:
①:新建Configuration.cs类,在其构造函数中进行相关配置。
②:改变数据库的初始化策略为,MigrateDatabaseToLatestVersion ,并在Configuration类中配置开启自动迁移:AutomaticMigrationsEnabled = true;
③:显式开启允许修改表结构:AutomaticMigrationDataLossAllowed = true; (默认是关闭的)
进行测试:
① 增加一列:改变Animal类,增加一个字段,刷新数据库,发现数据多了一列 (无需特别的配置),但后面再次增加,还是需要配置AutomaticMigrationDataLossAllowed设置为true
② 删除一列、修改列、改变列的属性:报错,提示需要将AutomaticMigrationDataLossAllowed设置为true, 设置后,修改或删除成功。
③ 增加一张表:增加一个AnimalKind类,运行代码,发现数据库多了一张表。
④ 删除表:注释掉:public DbSet<AnimalKind> AnimalKind { get; set; } ,运行代码,数据库中AnimalKind表被删除.
代码如下:
1 internal sealed class Configuration : DbMigrationsConfiguration<dbContext6> 2 { 3 public Configuration() 4 { 5 AutomaticMigrationsEnabled = true; //启用自动迁移 6 AutomaticMigrationDataLossAllowed = true; //更改数据库中结构(增加、删除列、修改列、改变列的属性、增加、删除、修改表),需要显示开启。 7 } 8 9 }
1 public class dbContext6 : DbContext 2 { 3 4 public dbContext6() 5 : base("name=dbContext6") 6 { 7 8 //数据库迁移配置 9 10 //数据库迁移的初始化方式 11 Database.SetInitializer(new MigrateDatabaseToLatestVersion<dbContext6, Configuration>("dbContext6")); 12 13 14 15 } 16 17 public DbSet<Animal> Animal { get; set; } 18 19 public DbSet<AnimalKind> AnimalKind { get; set; } 20 21 22 protected override void OnModelCreating(DbModelBuilder modelBuilder) 23 { 24 base.OnModelCreating(modelBuilder); 25 } 26 27 }
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。