返回

EF Core 数据库迁移最佳实践:从开发到生产环境的完整指南

2026-06-01 EF Core 数据库 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 策略后,即使数据库结构持续演进,也能保持部署稳定、环境一致,并显著降低线上事故风险。

顶部