1.添加初始化数据(Seed)

  我们可以在初始化数据库的过程中给数据库添加一些数据。为了实现初始化数据(seed data)我们必须创建一个自定义的数据库初始化器(DB initializer),并重写其中的Seed方法。

  下边的栗子展示在School数据库中给Standard表添加默认的数据:

第一步:创建自定义初始化器

//继承三种内置的初始化器中的DropCreateDatabaseAlways
public class SchoolDBInitializer : DropCreateDatabaseAlways<SchoolDBContext>
{
protected override void Seed(SchoolDBContext context)
{
IList<Standard> defaultStandards = new List<Standard>(); defaultStandards.Add(new Standard() { StandardName = "Standard 1", Description = "First Standard" });
defaultStandards.Add(new Standard() { StandardName = "Standard 2", Description = "Second Standard" });
defaultStandards.Add(new Standard() { StandardName = "Standard 3", Description = "Third Standard" }); context.Standards.AddRange(defaultStandards);
     //初始化数据
base.Seed(context);
}
}

第二步.将自定义的数据库初始化器添加到context中

public class SchoolContext: DbContext
{
public SchoolContext(): base("SchoolDB")
{
Database.SetInitializer(new SchoolDBInitializer());
} public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
}

2.数据库迁移策略

  前边我们已经知道了EF中的数据库迁移策略(CreateDatabaseIfNotExists,DropCreateDatabaseIfModelChanges, and DropCreateDatabaseAlways.),但是因为这些策略都是删除旧的数据库然后创建一个新的数据库,所以使用这些策略会造成数据库中的数据(不是seed data的数据)、存储过程、触发器等内容丢失

  针对上边的问题,EF提供了一个新的数据库初始化器 MigrateDatabaseToLastestVersion,这个工具在实体模型改变时自动帮我们更新数据库,且不会造成数据丢失。

下边介绍两种更新数据库的方法:

1.自动迁移

第一步:

在程序包管理器控制台输入

enable-migrations –EnableAutomaticMigration:$true

执行成功后,EFAp创建了一个继承自DbMigrationConfiguration类的Configuration类,如下

    internal sealed class Configuration : DbMigrationsConfiguration<EF6Demo.SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;//自动迁移为true
AutomaticMigrationDataLossAllowed = true;//允许数据丢失,默认生成时没有这一项(不添加这一项时,只在添加/删除实体类时自动生成,如果我们删除了实体类的一个属性就会抛出异常)
ContextKey = "EF6Demo.SchoolContext";
} protected override void Seed(EF6Demo.SchoolContext context)
{
// This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
}
}

第二步:

把数据库初始化器添加到配置中,context代码如下:

    public class SchoolContext : DbContext
{
public SchoolContext() {
//添加MigrateDatabaseToLatestVersion数据库初始化器
Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>());
}
public virtual DbSet<Student> Students { get; set; }
public virtual DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}

完成上边两步,当我们修改实体类时运行程序就会自动更新数据库。

2.使用代码迁移

  上边我们了解了通过自动迁移来更新数据库,这里介绍通过代码更新数据库的方法。通过代码更新数据库的功能更强大,如我们可以给数据库的列添加默认值,添加计算列等。

  使用代码迁移,我们在程序包控制台执行以下过程:

1.Enable-Migrations [-f]

  这条命令会生成一个Configuration文件,当配置文件存在时可通过-f后缀强制覆盖旧文件。执行成功后添加了Migrations文件夹,文件夹中包含一个Configuration配置类,如下:

Configuration配置类代码如下:

    internal sealed class Configuration : DbMigrationsConfiguration<EF6Demo.SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
ContextKey = "EF6Demo.SchoolContext";
} protected override void Seed(EF6Demo.SchoolContext context)
{
// This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
}
}

2.Add-Migration [MigName]

  首先在context类中指定初始化器是MigrateDatabaseToLatestVersion初始化器,如下:

   public class SchoolContext : DbContext
{
public SchoolContext() {
//添加MigrateDatabaseToLatestVersion数据库初始化器
Database.SetInitializer(new MigrateDatabaseToLatestVersion<SchoolContext, Configuration>()); }
public virtual DbSet<Student> Students { get; set; }
public virtual DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}

在包管理器控制台执行:

 Add-Migration FirstInit

这会在Migration文件夹中生成一个<stamp>_name的迁移类:

迁移类的代码如下:

    public partial class FirstInit : DbMigration
{
//升级
public override void Up()
{
CreateTable(
"dbo.Standards",
c => new
{
StandardId = c.Int(nullable: false, identity: true),
StandardName = c.String(),
})
.PrimaryKey(t => t.StandardId); CreateTable(
"dbo.Students",
c => new
{
StudentId = c.Int(nullable: false, identity: true),
StudentName = c.String(),
Standard_StandardId = c.Int(),
})
.PrimaryKey(t => t.StudentId)
.ForeignKey("dbo.Standards", t => t.Standard_StandardId)
.Index(t => t.Standard_StandardId); }
//降级
public override void Down()
{
DropForeignKey("dbo.Students", "Standard_StandardId", "dbo.Standards");
DropIndex("dbo.Students", new[] { "Standard_StandardId" });
DropTable("dbo.Students");
DropTable("dbo.Standards");
}
}

我们可以看到迁移类中包含Up()和Down()方法,分别用于数据库的更新和回退。

3.Update-Database

① updata-database [-verbose]

  在程序包控制台中执行这条命令时,会执行Add-Migration命令创建的最新的迁移文件,并更新数据库

执行完上边三步数据库就生成了,以后当我们修改实体类时,执行Add-Migration [MigName]后再执行Update-Database [-verbose],就可方便地根据模型的变化更新数据库。

② update-database -TargetMigration:xxx

如果我们想回退到某一个版本时执行:

update-database -TargetMigration:FirstInit//数据库回退到第一次的版本

3.codeFirst中的设计器

  我们知道codeFirst模式中不支持设计器,设计器对我们理解实体间关系还是很有用的,怎么在code-first中使用设计器呢?Visual Studio Marketplace.点击链接下载工具,安装即可,安装完成重启VS,在context上点击右键,然后会有一个Entity Framework选项,如下图:

点击ViewEntity Data Model选项就可以自动生成设计器,如下:

这个工具十分好用,同时也支持生成Model XML和DDL SQL推荐使用。

EF CodeFirst系列(9)---添加初始化数据和数据库迁移策略的更多相关文章

  1. EF CodeFirst系列(2)---CodeFirst的数据库初始化

    1. CodeFirst的默认约定 1.领域类和数据库架构的映射约定 在介绍数据库的初始化之前我们需要先了解领域类和数据库之间映射的一些约定.在CodeFirst模式中,约定指的是根据领域类(如Stu ...

  2. 3.Code-First 约定(EF Code-First系列)

    前面,我们已经了解了Code-First利用领域类,怎么为我们创建数据库的简单示例.现在我们来学习一下Code-First约定吧. 什么是约定 约定说白了,就是基于一套规矩办事,这里就是基于你定义好的 ...

  3. EF CodeFirst系列(3)---EF中的继承策略(暂存)

    我们初始化数据库一节已经知道:EF为每一个具体的类生成了数据库的表.现在有了一个问题:我们在设计领域类时经常用到继承,这能让我们的代码更简洁且容易管理,在面向对象中有“has  a”和“is a”关系 ...

  4. EF CodeFirst系列(1)---CodeFirst简单入门

    1.什么是CodeFirst 从EF4.1开始,EF可以支持CodeFirst开发模式,这种开发模式特别适用于领域驱动设计(Domain Driven Design,大名鼎鼎的DDD).在CodeFi ...

  5. EF CodeFirst系列(6)---配置1对1,1对多,多对多关系

    这一节介绍EF CodeFirst模式中的1对0/1,1对多,多对多关系的配置,只有梳理清楚实体间的关系,才能进行愉快的开发,因此这节虽然很简单但是还是记录了一下. 1. 1对0/1关系配置 1. 通 ...

  6. MySQL基础之 恢复数据和数据库迁移

    1.mysql命令或者source命令恢复数据 这两个命令在进行恢复数据的时候要检查是否创建数据库.如果数据库不存在,则恢复失败. 数据库迁移 1.相同版本的mysql数据库之间的迁移. mysqld ...

  7. 4.DB Initialization(数据库初始化)[EF Code-First系列]

    前面的例子中,我们已经看到了Code-First自动为我们创建数据库的例子. 这里我们将要学习的是,当初始化的时候,Code-First是怎么决定数据库的名字和服务的呢??? 下面的图,解释了这一切! ...

  8. EF CodeFirst系列(4)--- 数据注释属性

    EFCodeFirst模式使用的是约定大于配置的编程模式,这种模式利用默认约定根据我们的领域模型建立概念模型.然后我们也可以通过配置领域类来覆盖默认约定. 覆盖默认约定主要用两种手段: 1.数据注释属 ...

  9. 2.简单的Code First例子(EF Code-First系列)

    现在假想,我们想要为讴歌学校创建一个应用程序,这个程序需要能够来添加或者更新学生,分数,教师还有课程信息. 代替之前我们的做法:先是创建数据库,现在我们不这么做,我们先来创建领域类,首先我来创建两个简 ...

随机推荐

  1. (四)Exploring Your Cluster

    The REST API Now that we have our node (and cluster) up and running, the next step is to understand ...

  2. js如何调用php文件内显示的数值到html?

    index.html <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.9. ...

  3. STM32F40G-EVAL_UC/OS III

    micrum官网下载uc/os程序包: 包含文件cotex_M4.h:

  4. Shiro学习(一)——Shiro简介

    Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大 ...

  5. MyExceptionFilter 异常注入

    public class MyExceptionFilter : IExceptionFilter { private ILogService logService; public MyExcepti ...

  6. vue.js实战——方法设置默认参数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 从源码看springboot默认的资源文件和配置文件所在位置

    首先,使用的springboot版本是2.X,在这里写一点学习springboot的记录 springboot需要配置的不多,但也并不是完全不需要配置就可以顺畅使用,这里看一下它默认的配置 首先,看一 ...

  8. oracle创建表空间等相关语句

    在数据库可视化工具中执行以下语句,可建立Oracle表空间. 主要分为四步 1.创建临时表空间 create temporary tablespace xuanwu_temp tempfile 'D: ...

  9. A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse.

    cp -r /home/cuthead/android-studio/jre /home/cuthead/adt-bundle-linux-x86_64-20131030/eclipse/jre 使用 ...

  10. 4.ansible的delegate_to

    完成发布流程如下 first 修改nginx 配置文件下线 web1-2 使用 delegate_to 将默认hosts指定为 nginx主机 使用remote_user 将用户 锁定为 root s ...