EF Code First模式下移除模型列后数据库未同步删除的问题
你碰到的这个问题其实在EF自动迁移场景里挺常见的,咱们先把你的场景理清楚,再一步步分析原因和解决办法。
你的操作场景回顾
首先是初始的table1模型:
public class table1 { public Int64 Id { set; get; } public Int64 AutomotiveId { set; get; } public string Status { set; get; } public Int64 PlaqueCoded { set; get; } public Int64 ReferenceCount { set; get; } }
之后你添加了Price列,模型更新为:
public class table1 { public Int64 Id { set; get; } public Int64 AutomotiveId { set; get; } public string Status { set; get; } public Int64 PlaqueCoded { set; get; } public Int64 ReferenceCount { set; get; } public Int64 Price{ set; get; } }
等你把Price列从模型里移除后,数据库里的该列却没有被自动删除,你的迁移配置是:
public class MigrationsConfiguration : DbMigrationsConfiguration<DataContext> { public MigrationsConfiguration() { this.AutomaticMigrationDataLossAllowed = true; this.AutomaticMigrationsEnabled = true; } }
为什么EF没自动删除这个列?
主要有这几个可能的原因:
自动迁移没被触发
EF的自动迁移只会在应用启动时,检测到模型与数据库schema不匹配,且满足配置条件时才会执行。如果移除Price列后你没重启应用,或者启动时因为某些原因(比如初始化顺序问题)没触发迁移检查,数据库自然不会同步变更。迁移历史表的状态冲突
EF的__MigrationHistory表会记录每一次迁移的状态。如果之前添加Price列的操作已经生成了迁移记录,而你移除列的变更没有被自动迁移捕获并生成新的记录,EF会认为当前模型和已记录的迁移状态是匹配的,不会执行删除操作。列存在数据库依赖
如果Price列被添加了索引、外键约束,或者有视图、存储过程等数据库对象依赖它,哪怕你设置了AutomaticMigrationDataLossAllowed = true,EF自动迁移也可能跳过删除操作——因为这种删除可能会破坏数据库的完整性,自动迁移在这种场景下会保守处理。
解决办法
针对这些原因,你可以试试下面的方案:
手动生成迁移脚本(最稳妥)
放弃自动迁移的不确定性,手动生成明确的删除列迁移。打开Package Manager Console,执行以下命令:Add-Migration RemovePriceColumnFromTable1 Update-Database这会生成包含删除
Price列代码的迁移文件,然后强制同步到数据库,效果最可靠。清理列的数据库依赖
先手动登录数据库,检查Price列是否有索引、约束或其他依赖对象,手动删除这些依赖后,再重启应用触发自动迁移,这次EF应该能顺利删除列。重置迁移历史(仅限开发环境)
如果迁移历史表的状态已经混乱,可以先备份数据库,然后删除__MigrationHistory表,再重新初始化迁移:Add-Migration InitialCreate -Force Update-Database -Force注意:这个操作会清空所有迁移记录,绝对不能在生产环境使用,只适合开发环境快速重置状态。
内容的提问来源于stack exchange,提问作者Ehsan Akbar

