无法从PK中删除身份属性

时间:2013-11-22 19:43:55

标签: entity-framework-5 ef-migrations

我需要将我的一个表上的主键的数据类型更改为int的字符串(我没有说我想要...)。迁移生成了这段代码:

AlterColumn("dbo.Venues", "ID", c => c.String(nullable: false, maxLength: 128));

这会导致SQL服务器抱怨数据类型必须是int,bigint等,因为该列是标识列。我添加了以下内容,但似乎没有效果:

AlterColumn("dbo.Venues", "ID", c => c.Int(identity:false));

问题:如何进行迁移以将数据类型从int更改为string?

以下内容可能与我的问题有关,但不一定如此: 迁移生成的唯一代码是上面显示的第一个AlterColumn。当以本机生成的方式运行时,迁移导致SQL Server抱怨它无法更改列,因为它存在依赖关系。实际上唯一的依赖是它是一个PK(没有表将它作为FK引用)。我将迁移修改为如下所示,现在我收到如上所示的数据类型错误。

DropPrimaryKey("dbo.Venues");
AlterColumn("dbo.Venues", "ID", c => c.Int(identity:false));
AlterColumn("dbo.Venues", "ID", c => c.String(nullable: false, maxLength: 128));
AddPrimaryKey("dbo.Venues", "ID");

2 个答案:

答案 0 :(得分:3)

只能通过重新创建表来从列中删除标识规范。查看ALTER TABLE - ALTER COLUMN语句:没有语法可以更改(添加或删除)标识规范。

因此,我担心您必须手动执行此操作,并为后续迁移重新开始。

BTW Sql Server Management Studio不会帮助您这样做。您可能希望使用Toad for Sql Server。当您删除标识规范时,它会创建一个完整的表重建脚本。

答案 1 :(得分:2)

至少对于某些版本的SQL Server,可以在不删除/重新创建数据库的情况下完成此操作。据报道,它不适用于Azure(或者不是2015年的评论)。灵感来自this answer,这是我的Up()方法。

请注意,我在这张桌子上没有任何外键,所以不需要支持链接答案所涵盖的皱纹

    public override void Up()
    {
        DropPrimaryKey("dbo.Products"); // Should be same as ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
        Sql("alter table dbo.Products add tempId int NOT NULL default -1");
        Sql("update dbo.Products set tempId = Id;");
        // Won't work. Can't remove identity: AlterColumn("dbo.Products", "Id", c => c.Int(nullable: false));
        Sql("alter table dbo.Products drop column Id");
        Sql("EXEC sp_rename 'Products.tempId', 'Id', 'COLUMN'");
        AddPrimaryKey("dbo.Products", "Id"); // Should be same as ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id)
    }