如何使用EF迁移更改主键和外键的数据类型?

时间:2019-02-01 16:30:41

标签: c# sql-server entity-framework-6

我必须将已经存在的数据库/表中使用的所有主键和外键的数据类型从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

2 个答案:

答案 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) 
    // ...
}