EF Core 迁移:在存在时删除唯一约束
Posted
技术标签:
【中文标题】EF Core 迁移:在存在时删除唯一约束【英文标题】:EF Core Migrations: Drop Unique Constraint when it exists 【发布时间】:2022-01-23 20:16:41 【问题描述】:上下文
我在 SQL Server 中有一个表,它在表的四列上有一个唯一索引。
当使用 EF Core 迁移中的 migrationBuilder.AlterColumn
时,它首先尝试编写一个无法在 UNIQUE INDEX
上执行的 DROP INDEX
脚本。为了解决这个问题,我可以使用migrationBuilder.DropUniqueConstraint
,只要该约束存在。
问题
一些开发者在本地没有数据库,他们会从头开始运行所有的迁移脚本。这意味着将创建UNIQUE INDEX
,但没有数据,因此不会有UNIQUE CONSTRAINT
。在这种情况下,会因为约束不存在而引发 SQL 异常。
我尝试使用migrationBuilder.Sql
并执行IF EXISTS
语句,它检查约束是否存在,然后删除它。但是,它似乎没有正确执行,或者根本没有执行。
问题?
我的陈述是否有问题,或者有更简单的方法来解决这个问题?
声明
migrationBuilder.Sql(@"
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME='CONSTRAINT_NAME')
BEGIN
ALTER COLUMN COLUMN_NAME DROP CONSTRAINT CONSTRAINT_NAME
END");
【问题讨论】:
那么为什么有时会有唯一约束,有时会有唯一索引呢?这听起来不对。 在迁移 InitialCreate 脚本中,我们添加了唯一索引。只有当我们在表中有数据时,约束才会出现。 约束不会神奇地出现。唯一约束创建索引,反之则不行。 这是有道理的。您是否知道当前如何在我们的数据库中存在唯一约束,而无需手动添加任何内容? 可能有人从其他工具(例如 SSMS)添加约束和索引。您不应该在代码优先的应用程序数据库中这样做,因为在某些时候它可能/将会破坏迁移。 【参考方案1】:根据 cmets,我们确定了问题所在。
我们最初采用 EF Core 数据库优先方法,其中 SSMS 用于编写 UNIQUE CONSTRAINT
脚本,而后者又创建了 UNIQUE INDEX
。
后来我们使用带有迁移的脚手架来进行InitialCreate
迁移,首先迁移到代码。在这一步中,它生成了modelBuilder
代码来创建UNIQUE INDEX
,但不是约束。这意味着我们的迁移脚本不再与我们现有数据库的状态同步,这些数据库最初是数据库优先的。
解决方案是停止尝试在迁移脚本中删除约束(我们甚至不需要),并将其从我们现有的数据库中删除。
【讨论】:
以上是关于EF Core 迁移:在存在时删除唯一约束的主要内容,如果未能解决你的问题,请参考以下文章
EF Core 中是不是有用于唯一约束的数据注释(代码优先)?