ef core迁移需模型快照、di链与数据库提供程序协同,常见错误如dbcontext构造失败、update-database连错库、sql生成异常及多人迁移冲突,须按规范配置无参构造、显式指定上下文与连接字符串、人工审查迁移脚本并严格同步历史表与文件。

EF Core 迁移不是“改完模型就 update”就能生效的流程,跳过 dotnet ef migrations add 直接跑 dotnet ef database update,数据库结构完全不会变,而且不报错——它只是静默跳过。
为什么 dotnet ef migrations add 总报 “Unable to create an object of type 'AppDbContext'”
这个错误不是 DbContext 写得不对,而是 EF CLI 工具根本没机会走到你的 DI 容器里去解析依赖。它尝试用反射直接 new 实例,所以:
- 如果
AppDbContext构造函数只接受DbContextOptions<appdbcontext></appdbcontext>,而你没注册任何服务(CLI 不读Program.cs),就会崩 - 项目里有多个 DbContext 子类,但没加
--context AppDbContext,CLI 就随机选一个或报错 - 没写无参构造函数,且
OnConfiguring也没重写,CLI 就连连接字符串都不知道从哪来
最稳妥的解法是加一个仅用于迁移的无参构造:
public AppDbContext() : base(new DbContextOptionsBuilder<appdbcontext>()
.UseSqlServer("Server=.;Database=TestDb;Trusted_Connection=true;")
.Options)
{ }</appdbcontext>
或者更推荐:显式指定上下文和项目路径,绕过构造函数陷阱:
dotnet ef migrations add InitialCreate --project MyDataProject --startup-project MyWebProject --context AppDbContext
dotnet ef database update 连错了库,或者压根没更新表结构
Update-Database 默认不看 appsettings.json,它优先读 Program.cs 中 AddDbContext 时硬编码的连接字符串。常见踩坑点:
- 你在
appsettings.json改了ConnectionStrings:DefaultConnection,但Program.cs里还是写死的旧地址 - 用了
AddDbContextPool,却忘了在UseSqlServer里传builder.Configuration.GetConnectionString("DefaultConnection") - 想切测试库,但没加
-c参数,结果更新到了本地开发库
安全做法是显式传连接字符串:
dotnet ef database update -c "Server=localhost\SQLEXPRESS;Database=MyAppTest;Trusted_Connection=true;"
或者确保 Program.cs 的注册逻辑真正读取配置项,而不是字符串字面量。
生成的迁移文件里 Up() 是空的,或者 SQL 缺索引、字段没加 nullable=false
EF Core 不对比数据库,它只对比当前代码模型和上一次生成的 ModelSnapshot.cs。所以:
- 手动删过迁移文件但没删
ModelSnapshot.cs,EF 就认为“模型没变”,生成空Up() - 你加了
[Required]或用了 Fluent API 配置索引,但上次migrations add没成功执行,快照没更新,新变更就不会进 SQL - 改过历史迁移里的
Up()方法(比如删了某行Annotation),后续所有迁移都基于这个被篡改的快照推导,越错越远
检查迁移链是否干净:
- 确认
Migrations/下有*_InitialCreate.cs和对应.Designer.cs;没有就先补一个 - 删迁移文件时,必须把同名的
.cs和.Designer.cs一起删,否则快照仍指向旧状态 - 实体类改完后,必须先
add新迁移,再update,不能跳步
迁移本质是模型版本管理,不是自动同步工具。快照文件、构造函数兼容性、连接字符串来源这三处最容易被忽略,但任意一处断掉,整个流程就静默失效——它不会报错,只会什么也不做。











