EF Core生产环境推送迁移时是否不应包含种子数据?
EF Core 种子数据配置问题解答
核心问题根因
你遇到的迁移自动生成对等Delete+Insert操作、注释种子数据后生成删除操作的问题,本质是不符合EF Core HasData()的使用规则:HasData()依赖固定的主键值识别种子数据,每次生成迁移时都会重新计算你写在HasData()里的所有字段值,如果你用了Id = Guid.NewGuid()这种动态生成逻辑,每次生成迁移时得到的主键都不一样,EF就会认为旧的种子数据已经被移除、要插入新的种子数据,自然会生成删除旧数据插入新数据的操作。而你注释所有HasData()配置后,EF判定你不需要这些种子数据了,就会生成删除全部历史种子数据的迁移操作。
问题1:生产环境推送的迁移是否不应包含种子数据?
生产环境迁移可以安全包含种子数据,出问题是使用姿势错误而非该功能本身不适合生产。只要遵守以下规则即可:
- 所有种子数据的主键、唯一键必须使用硬编码的固定值,禁止使用
Guid.NewGuid()、DateTime.Now等动态生成逻辑 - 仅把系统运行必须、极少变更的预置数据放到
HasData()中管理,比如字典枚举值、系统默认角色、内置管理员账号等
问题2:是否应该在准备发布时删除所有种子数据?
不需要全删,按种子数据的用途分类处理即可:
- 测试用模拟数据:发布前必须删除对应
HasData()配置,生成迁移后手动确认Up方法里的删除操作仅针对测试数据,无误后再上线 - 生产必须的预置数据:只要改成硬编码固定主键的配置,完全可以保留,无需删除
额外给出避免误删生产数据的强制规范:
- 每次生成迁移后,必须手动检查
Up方法的所有操作,绝对不能出现你预期外的DeleteData、DropTable、AlterColumn(丢失精度/非空变更)这类风险操作,有异常就废弃该迁移重新调整配置 - 生产执行迁移前,必须在和生产配置完全一致的预发布环境模拟执行,确认结果符合预期再操作生产
- 任何迁移操作前必须备份全量生产数据库,出现异常可以立即回滚
问题3:种子数据是否仅用于测试,还是可以用于系统初始化预置数据?
HasData()的设计本身就支持两类场景:
- 测试场景:可以单独编写仅在开发/测试环境加载的
HasData()配置,放模拟业务数据方便调试,生产环境不加载这部分配置即可 - 系统预置数据场景:完全可以用来管理生产环境需要的初始化数据,只要遵守固定主键、仅管理不变/极少变更数据的规则即可。如果你的预置数据后续允许业务侧修改,就不要用
HasData()管理,否则后续你调整HasData()配置生成的迁移会覆盖业务侧的修改,这类数据建议用独立的初始化SQL脚本/接口,仅在系统首次启动时执行一次。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

