第十七节: 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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

 

posted @ 2017-11-11 21:22  Yaopengfei  阅读(2275)  评论(3编辑  收藏  举报