咱们能够在初始化数据库的过程当中给数据库添加一些数据。为了实现初始化数据(seed data)咱们必须建立一个自定义的数据库初始化器(DB initializer),并重写其中的Seed方法。html
下边的栗子展现在School数据库中给Standard表添加默认的数据:数据库
第一步:建立自定义初始化器ide
//继承三种内置的初始化器中的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; } }
前边咱们已经知道了EF中的数据库迁移策略(CreateDatabaseIfNotExists,DropCreateDatabaseIfModelChanges, and DropCreateDatabaseAlways.),可是由于这些策略都是删除旧的数据库而后建立一个新的数据库,因此使用这些策略会形成数据库中的数据(不是seed data的数据)、存储过程、触发器等内容丢失。ui
针对上边的问题,EF提供了一个新的数据库初始化器 MigrateDatabaseToLastestVersion,这个工具在实体模型改变时自动帮咱们更新数据库,且不会形成数据丢失。spa
下边介绍两种更新数据库的方法:设计
第一步:3d
在程序包管理器控制台输入code
enable-migrations –EnableAutomaticMigration:$true
执行成功后,EFAp建立了一个继承自DbMigrationConfiguration类的Configuration类,以下htm
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); } }
完成上边两步,当咱们修改实体类时运行程序就会自动更新数据库。
上边咱们了解了经过自动迁移来更新数据库,这里介绍经过代码更新数据库的方法。经过代码更新数据库的功能更强大,如咱们能够给数据库的列添加默认值,添加计算列等。
使用代码迁移,咱们在程序包控制台执行如下过程:
这条命令会生成一个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. } }
首先在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()方法,分别用于数据库的更新和回退。
① updata-database [-verbose]
在程序包控制台中执行这条命令时,会执行Add-Migration命令建立的最新的迁移文件,并更新数据库。
执行完上边三步数据库就生成了,之后当咱们修改实体类时,执行Add-Migration [MigName]后再执行Update-Database [-verbose],就可方便地根据模型的变化更新数据库。
② update-database -TargetMigration:xxx
若是咱们想回退到某一个版本时执行:
update-database -TargetMigration:FirstInit//数据库回退到第一次的版本
咱们知道codeFirst模式中不支持设计器,设计器对咱们理解实体间关系仍是颇有用的,怎么在code-first中使用设计器呢?Visual Studio Marketplace.点击连接下载工具,安装便可,安装完成重启VS,在context上点击右键,而后会有一个Entity Framework选项,以下图:
点击ViewEntity Data Model选项就能够自动生成设计器,以下:
这个工具十分好用,同时也支持生成Model XML和DDL SQL推荐使用。