EF Core 数据库迁移最佳实践:从开发到生产环境的完整指南
2026-06-01 56 0
在基于 .NET 的项目开发中,Entity Framework Core(简称 EF Core)数据库迁移是保证数据结构持续演进的重要能力。随着业务需求不断变化,数据库表结构不可避免会新增字段、调整索引甚至拆分表,如果缺少规范的迁移策略,很容易导致环境不一致、部署失败或数据丢失。
本文将从实际项目经验出发,系统介绍 EF Core 数据库迁移最佳实践,包括迁移命名、团队协作、生产环境发布以及常见踩坑问题,帮助开发者建立稳定、安全、可维护的数据库变更流程。
什么是 EF Core 数据库迁移
EF Core Migration 是一种基于 Code First 的数据库版本管理机制,它会比较当前实体模型与历史快照之间的差异,自动生成数据库变更脚本,使数据库结构能够随着代码迭代逐步升级,而无需手写大量 SQL。官方文档指出,Migration 的核心目标是保持数据模型与数据库结构同步,同时尽可能保留已有数据。
常见命令包括:
dotnet ef migrations add InitDatabase
dotnet ef database update
开发阶段通过 Migration 可以快速完成表结构演进,但在正式环境中,如果直接执行更新命令,则存在一定风险,因此需要建立更规范的实践流程。
最佳实践一:每次业务变更对应一次 Migration
很多开发者会问,EF Core 数据库迁移应该一个表一个 Migration,还是多个表合并?
实际经验更推荐按业务变更维度创建 Migration,而不是按单张表拆分。例如用户模块上线时,同时新增用户表、角色表和权限表,可以统一生成一次 Migration,而不是每新增一个实体就生成一次。社区经验普遍认为,过度细分 Migration 并不会带来明显收益,反而会增加维护复杂度。
推荐命名方式:
AddUserPermissionModule
AddOrderAuditLog
RefactorProductIndex
良好的命名能够帮助团队快速理解数据库变更历史。
最佳实践二:始终检查生成的 Migration 文件
不要完全相信自动生成代码。
EF Core 在生成迁移时,有时会错误识别结构变化,例如:
- 修改字段名被识别成删除旧字段 + 新增字段
- 索引变化未按预期生成
- 外键删除顺序不正确
官方明确建议,在迁移进入生产环境之前必须检查生成内容,尤其是涉及删除列、修改字段类型、索引调整等高风险操作。
最佳实践三:开发环境允许自动更新,生产环境禁止直接 Update Database
很多初学者习惯使用 dotnet ef database update 直接更新生产数据库。
但官方并不推荐这样做,因为:
- 无法提前审核 SQL
- 回滚困难
- 容易误删字段
- 多环境部署风险较高
更推荐的做法是先生成 SQL 脚本:
dotnet ef migrations script
或者生成幂等脚本:
dotnet ef migrations script --idempotent
这样 DBA 或开发团队可以提前审核执行 SQL,再上线部署。官方将 SQL Script 视为生产环境迁移的推荐方式。
最佳实践四:使用幂等迁移脚本管理多环境
大型项目通常存在:
- 本地环境
- 测试环境
- 预发布环境
- 生产环境
这些数据库版本可能并不一致。
此时建议使用幂等脚本(Idempotent Script):
dotnet ef migrations script --idempotent
其优势在于:
- 自动识别已执行 Migration
- 避免重复执行
- 支持不同数据库版本平滑升级
- 更适合 CI/CD 自动化发布
官方文档特别推荐在无法确定数据库版本状态时使用幂等脚本。
最佳实践五:团队开发不要随意修改已提交 Migration
多人协作时,经常出现:A 开发者新增字段,B 开发者新增索引,最终产生 Migration 冲突。
社区经验表明,一个重要原则是:已经提交到共享分支的 Migration 不要修改、删除或重写。
如果主分支新增了数据库改动,应先同步主分支,再重新生成自己的 Migration,而不是直接覆盖已有迁移。否则容易导致快照冲突或环境不一致。团队实践中,很多开发者会在 CI 阶段验证 Migration 是否能够完整执行,以减少上线风险。
推荐流程:
拉取最新 main
↓
合并主分支
↓
重新生成 Migration
↓
本地执行验证
↓
提交 PR
最佳实践六:不要在生产环境启动时自动执行 Migrate
有些项目喜欢在启动时写:
await context.Database.MigrateAsync();
虽然方便,但官方明确提醒:生产环境不建议这样做。原因包括:
- 多实例部署时可能并发执行迁移
- 应用权限过高
- 出问题难以回滚
- 缺乏 SQL 审核流程
它更适合开发环境或者测试环境。生产环境建议使用 SQL Script 或 Migration Bundle 独立执行。
最佳实践七:把数据库迁移纳入 CI/CD 流程
成熟项目通常会把 Migration 纳入自动化流程,例如:
代码提交
↓
自动测试
↓
执行 Migration 验证
↓
生成 SQL Script
↓
人工审核
↓
生产发布
EF Core 还支持生成 Migration Bundle:
dotnet ef migrations bundle
它可以打包成独立可执行文件,方便部署且不依赖完整开发环境。官方认为它在自动化发布中具有明显优势。
EF Core 数据库迁移常见错误
开发过程中,以下问题尤其常见:
1. 删除 Migration 文件但未回滚数据库
仅删除文件 Migrations/ 并不会修改数据库状态。
正确方式:
dotnet ef database update 上一个版本
dotnet ef migrations remove
2. 使用 EnsureCreated 与 Migration 混用
官方明确指出:不要同时使用 EnsureCreated() 和 Migrate(),因为 EnsureCreated 会绕过 Migration 机制,后续迁移可能直接失效。
3. Migration 命名混乱
例如:
- test
- newdb
- fix1
- fix2
建议使用如下命名:
- AddUserAvatar
- AddOrderIndex
- RefactorRolePermission
更容易排查问题。
总结
EF Core 数据库迁移并不仅仅是执行几个命令,而是一套数据库版本管理规范。
在实际项目中,更推荐遵循以下原则:
- 一个业务功能对应一次 Migration
- 始终审核自动生成代码
- 开发环境允许自动更新,生产环境使用 SQL Script
- 多环境部署优先使用幂等脚本
- 不修改已提交 Migration
- 避免生产环境自动执行 Migrate
- 将数据库迁移纳入 CI/CD 流程
当团队建立起规范的 Migration 策略后,即使数据库结构持续演进,也能保持部署稳定、环境一致,并显著降低线上事故风险。