ef mysql 默认值_EF CodeFirst系列(9)---添加初始化数据和数据库迁移策略

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

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

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

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

//继承三种内置的初始化器中的dropcreatedatabasealways

public class schooldbinitializer : dropcreatedatabasealways

{

protected override void seed(schooldbcontext context)

{

ilist defaultstandards = new list();

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 students { get; set; }

public dbset 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

{

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.addorupdate() helper extension method

// to avoid creating duplicate seed data.

}

}

第二步:

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

public class schoolcontext : dbcontext

{

public schoolcontext() {

//添加migratedatabasetolatestversion数据库初始化器

database.setinitializer(new migratedatabasetolatestversion());

}

public virtual dbset students { get; set; }

public virtual dbset standards { get; set; }

protected override void onmodelcreating(dbmodelbuilder modelbuilder)

{

base.onmodelcreating(modelbuilder);

}

}

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

2.使用代码迁移

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

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

1.enable-migrations [-f]

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

7ac7e231155098660052538a7689ae1b.png

configuration配置类代码如下:

internal sealed class configuration : dbmigrationsconfiguration

{

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.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());

}

public virtual dbset students { get; set; }

public virtual dbset standards { get; set; }

protected override void onmodelcreating(dbmodelbuilder modelbuilder)

{

base.onmodelcreating(modelbuilder);

}

}

在包管理器控制台执行:

add-migration firstinit

这会在migration文件夹中生成一个_name的迁移类:

bce90100d219ed832a627d25d863eeda.png

迁移类的代码如下:

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选项,如下图:

494cb78cbecc0b3362da99bb106721d3.png

点击viewentity data model选项就可以自动生成设计器,如下:

c5ec66b1f045434261a2f4ca73527ac3.png

这个工具十分好用,同时也支持生成model xml和ddl sql推荐使用。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值