Entity Framework Code First删除列被外键约束阻止的解决求助
问题描述
尝试从PRODUCT表删除ID_PRODUCT_PARENT列,已从模型类移除该列并执行迁移命令生成SQL脚本,但执行update-database -Verbose时失败,错误提示:
The object 'FK_PRODUCT_PRODUCT' is dependent on column 'ID_PRODUCT_PARENT'.
ALTER TABLE DROP COLUMN ID_PRODUCT_PARENT failed because one or more objects access this column
自动生成的迁移脚本仅处理了该列的默认约束,未包含删除外键FK_PRODUCT_PRODUCT的语句,担心手动删除外键会引发问题,求解决办法。
相关脚本:
- 自动生成的迁移SQL:
DECLARE @var0 nvarchar(128) SELECT @var0 = name FROM sys.default_constraints WHERE parent_object_id = object_id(N'dbo.PRODUCT') AND col_name(parent_object_id, parent_column_id) = 'ID_PRODUCT_PARENT'; IF @var0 IS NOT NULL EXECUTE('ALTER TABLE [dbo].[PRODUCT] DROP CONSTRAINT [' + @var0 + ']') ALTER TABLE [dbo].[PRODUCT] DROP COLUMN [ID_PRODUCT_PARENT] INSERT [dbo].[__MigrationHistory]--------------------------------------------------XXXX
- 外键创建脚本:
ALTER TABLE [dbo].[PRODUCT] WITH CHECK ADD CONSTRAINT [FK_PRODUCT_PRODUCT] FOREIGN KEY([ID_PRODUCT_PARENT]) REFERENCES [dbo].[PRODUCT] ([ID_PRODUCT]) GO ALTER TABLE [dbo].[PRODUCT] CHECK CONSTRAINT [FK_PRODUCT_PRODUCT] GO
解决方法
方法一:修改迁移脚本,先删外键再删列
因为外键FK_PRODUCT_PRODUCT依赖要删除的列,必须先删除外键才能删除列。直接修改自动生成的SQL脚本,在删除默认约束之后、删除列之前添加删除外键的语句:
修改后的完整脚本:
DECLARE @var0 nvarchar(128) SELECT @var0 = name FROM sys.default_constraints WHERE parent_object_id = object_id(N'dbo.PRODUCT') AND col_name(parent_object_id, parent_column_id) = 'ID_PRODUCT_PARENT'; IF @var0 IS NOT NULL EXECUTE('ALTER TABLE [dbo].[PRODUCT] DROP CONSTRAINT [' + @var0 + ']') -- 新增删除外键的语句 ALTER TABLE [dbo].[PRODUCT] DROP CONSTRAINT [FK_PRODUCT_PRODUCT] GO ALTER TABLE [dbo].[PRODUCT] DROP COLUMN [ID_PRODUCT_PARENT] INSERT [dbo].[__MigrationHistory]--------------------------------------------------XXXX
修改完成后重新执行脚本,或者再次运行update-database即可。
方法二:通过Code First迁移代码添加删外键逻辑
如果不想手动改SQL,可以回到自动生成的迁移C#类,在Up()方法里添加删除外键的代码:
public override void Up() { // 新增删除外键的语句,放在删列之前 DropForeignKey("dbo.PRODUCT", "ID_PRODUCT_PARENT", "dbo.PRODUCT"); // 保留自动生成的删列代码 DropColumn("dbo.PRODUCT", "ID_PRODUCT_PARENT"); }
保存后重新生成迁移脚本,再执行update-database即可。
关于手动删外键的安全性
不用担心手动删除外键会出问题,只要确认两点:
- 这个外键确实只依赖
ID_PRODUCT_PARENT列(从错误提示和外键创建脚本可以确认) - 业务逻辑已经不需要这个自关联的外键关系(既然已经从模型类移除了对应属性,说明业务上已废弃)
如果不放心,删除前可以先备份表数据,防止意外情况。
内容的提问来源于stack exchange,提问作者nik
相关产品推荐
相关产品推荐

