【问题标题】:EF Core Migrations: Drop Unique Constraint when it existsEF Core 迁移:在存在时删除唯一约束
【发布时间】: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)添加约束和索引。您不应该在代码优先的应用程序数据库中这样做,因为在某些时候它可能/将会破坏迁移。

标签: c# sql-server asp.net-core entity-framework-core entity-framework-migrations


【解决方案1】:

根据 cmets,我们确定了问题所在。

我们最初采用 EF Core 数据库优先方法,其中 SSMS 用于编写 UNIQUE CONSTRAINT 脚本,而后者又创建了 UNIQUE INDEX

后来我们使用带有迁移的脚手架来进行InitialCreate 迁移,首先迁移到代码。在这一步中,它生成了modelBuilder 代码来创建UNIQUE INDEX,但不是约束。这意味着我们的迁移脚本不再与我们现有数据库的状态同步,这些数据库最初是数据库优先的。

解决方案是停止尝试在迁移脚本中删除约束(我们甚至不需要),并将其从我们现有的数据库中删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2018-08-05
    • 1970-01-01
    • 2016-08-10
    • 2021-09-30
    • 2011-08-06
    • 1970-01-01
    • 2018-10-08
    相关资源
    最近更新 更多