我必须将已经存在的数据库/表中使用的所有主键和外键的数据类型从int
更改为bigint
。
要变通解决以下错误...
MSG 5074,第16级,状态8,第1行
对象“主键约束名称”取决于列“主键列名称”。
ALTER TABLE ALTER COLUMN列名失败,因为一个或多个对象访问此列。
我首先必须删除约束,然后在以后重新创建它。这是我使用SSMS的方法:
alter table Meta.Playground
drop constraint Pk_Playground
go
alter table Meta.Playground
alter column id bigint not null
go
alter table Meta.Playground
add constraint Pk_Playground primary key (id)
go
但是使用实体框架的Up()
和Down()
方法做到这一点的最佳方法是什么?
我不知道如何从这些方法中检索键和约束名称。
通过使用SQL,我将按以下方式检索它们:
select COLUMN_NAME, CONSTRAINT_NAME
into #result
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
where TABLE_NAME = @table and TABLE_SCHEMA = @schema
答案 0 :(得分:1)
要使用EF迁移中的约束,您将需要直接执行SQL语句。您可以使用Sql函数来做到这一点。
例如:
public override void Up()
{
Sql("ALTER TABLE Meta.Playground DROP CONSTRAINT Pk_Playground");
}
要支持约束的动态名称,您将要传递一个获取该名称的SQL语句,然后执行ALTER语句。
这里有一个例子: EF migration for changing data type of columns
DECLARE @con nvarchar(128)
SELECT @con = name
FROM sys.default_constraints
WHERE parent_object_id = object_id('dbo.Received')
AND col_name(parent_object_id, parent_column_id) = 'FromNo';
IF @con IS NOT NULL
EXECUTE('ALTER TABLE [dbo].[Received] DROP CONSTRAINT ' + @con)
这就是您通过Sql函数传递的语句。
答案 1 :(得分:0)
我意识到解决这个问题的方法是复杂的方法。
添加一个额外的迁移步骤以一种非常简单的方式解决了我的问题。因此,无需其他SQL脚本。实体框架完全能够迁移主键和外键(至少我正在使用的版本6.1.3)。
这是使用适当的参数调用Add-Migration
之后的代码。
public override void Up()
{
DropForeignKey(...)
// ...
DropIndex(...)
// ...
DropPrimaryKey(...)
// ...
AlterColumn(...)
// ...
AddPrimaryKey(...)
// ...
CreateIndex(...)
// ...
AddForeignKey)
// ...
}