原文:
http://blog.bossma.cn/csharp/code-first-how-to-upgrade-database/
Code First模式
使用Code First模式开发数据库时,首先编写实体类,继承DbContext创建数据操作类,然后在这个基础上编写自己的业务处理程序,然后在系统运行前配置数据连接,当系统第一次运行时会自动创建数据库(当前版本中使用DropCreateDatabaseIfModelChanges策略时,系统第一次运行时如果数据库已经存在则会抛出异常,所以这个数据库是自动创建的),并根据实体类自动创建相应的数据表。
这种开发模式很好的体现了领域驱动设计的思想,特别适合业务系统的开发工作,好处很多,我就不多说了。
测试数据问题
但是对开发工作同样存在一些问题,比如修改实体类以后,数据库会重新创建,我们输入的测试数据会全部丢失,这样会导致一定的效率问题。对于这个问题官方提供了解决的办法:通过接口IDatabaseInitializer,实现自己的数据库初始化策略,当数据库重建后可以编写程序(Seed方法中)向数据表中插入特定的测试数据。
系统上线以后
但是系统上线以后,就不能这样搞了,真实的业务数据怎么能重新创建出来?如下是我的解决办法:
1、修改数据库初始化策略,使用CreateDatabaseIfNotExists(如果数据库不存在则创建数据库),这样当业务实体类修改后,数据库就不会自动重建了,数据自然保存下来;
2、去数据库中修改实体类对应的相关数据表,保证实体类属性与对应的数据表的字段保持一致。
这样在系统已经上线后,如果业务实体有变化,比如增加个属性之类的,两边(实体类和数据表)都修改下就好了;仔细考虑下应该先修改数据库,然后上传新的程序,保证程序运行的时候不会出现数据库映射问题。
EdmMetadata
在创建数据库时会自动创建一个表EdmMetadata,这个表用于比对模型与当前数据库是否匹配,如果实体发生变化,这个表里边的值就会和模型中计算出来的值不一致,从而实施数据库重建操作。但是如果使用CreateDatabaseIfNotExists策略,这个表就没什么用了,可以安全的删除掉。
进一步考虑
我们可以将这个系统中创建的数据表放到一个已经存在的数据库中,只需要修改数据连接属性即可。比如一个大的系统下有很多小的子系统,这些小的子系统对应的数据表都在这个大的数据库中,而每个子系统具体的开发模式可能不同,使用Code First模式开发的系统就可以按照上边的策略进行部署和更新维护。