第十七节: EF的CodeFirst模式的四种初始化策略和通过Migration进行数据的迁移

时间:2022-02-09 19:44:18

一. 四种初始化策略

  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 }