我怎样才能改变一个int ID列与EF迁移GUID? [英] How can I change an int ID column to Guid with EF migration?

查看:790
本文介绍了我怎样才能改变一个int ID列与EF迁移GUID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用EF code-第一的方针,并希望在编号字段更改为的GUID 但似乎无法得到下面的错误的过去。

这是我第一次迁移:

 公共部分类CreateDownloadToken:DbMigration
{
    公共覆盖无效向上()
    {
        CREATETABLE(
            dbo.DownloadTokens
            C =>新
            {
                ID = c.Int(可空:假的,身份:真)
                FILEID = c.Int()
                用户ID = c.String(可空:假的,最大长度:128)
                ValidUntil = c.DateTime(可空:假),
            })
            .PrimaryKey(T => t.Id)
            .ForeignKey(dbo.Files,T => t.FileId)
            .ForeignKey(dbo.Users,T => t.UserId,cascadeDelete:真)
            的.index(T => t.FileId)
            的.index(T => t.UserId);    }    公共覆盖无效向下()
    {
        DropForeignKey(dbo.DownloadTokens,用户ID,dbo.Users);
        DropForeignKey(dbo.DownloadTokens,FILEID,dbo.Files);
        DropIndex(dbo.DownloadTokens,新的[] {用户ID});
        DropIndex(dbo.DownloadTokens,新的[] {FILEID});
        DROPTABLE(dbo.DownloadTokens);
    }
}

后来我意识到,我需要我的GUID 编号列,所以我改变了我的模型文件:

 公共类DownloadToken
{
    [关键词,DatabaseGenerated(DatabaseGeneratedOption.Computed)
    公众的Guid标识{搞定;组; }    公众诠释? FILEID {搞定;组; }    [ForeignKey的(FILEID)]
    公共虚拟文件文件{搞定;组; }    [需要]
    公共字符串userid {搞定;组; }    [ForeignKey的(用户ID)]
    公共虚拟用户用户{搞定;组; }    [需要]
    公众的DateTime ValidUntil {搞定;组; }
}

在运行时添加迁移ChangeDownloadTokenIdToGuid 它生成这个文件:

 公共部分类ChangeDownloadTokenIdToGuid:DbMigration
{
    公共覆盖无效向上()
    {
        DropPrimaryKey(dbo.DownloadTokens);
        AlterColumn(dbo.DownloadTokens,ID,C = GT; c.Guid(可空:FALSE));
        AddPrimaryKey(dbo.DownloadTokens,ID);
    }    公共覆盖无效向下()
    {
        DropPrimaryKey(dbo.DownloadTokens);
        AlterColumn(dbo.DownloadTokens,ID,C = GT; c.Int(可空:假的,身份:真));
        AddPrimaryKey(dbo.DownloadTokens,ID);
    }
}

运行带有更新 - 数据库该文件会导致这个错误:

 标识列ID必须是数据类型为int,BIGINT,SMALLINT,TINYINT或十进制或数字的为0的规模,并限制为不可为空。

任何想法,为什么这可能发生?


解决方案

据造成的,因为它是不可能转换previous INT 类型标识的Guid 键入(正是尝试执行 AlterColumn 方法)。此外,错误信息提示你,新型标识的列的类型可以从一组之一: INT,BIGINT,SMALLINT,TINYINT或十进制或数字与0分的,对他们来说,有可能执行从 INT 转换类型。

解决方案 - 简单的丢弃编号列,然后用新的重新创建的Guid 键入,改变迁移这种方式:

 公共部分类ChangeDownloadTokenIdToGuid:DbMigration
{
    公共覆盖无效向上()
    {
        DropPrimaryKey(dbo.DownloadTokens);        DropColumn(dbo.DownloadTokens,ID);
        AddColumn(dbo.DownloadTokens,ID,C = GT; c.Guid(可空:假的,身份:真));        AddPrimaryKey(dbo.DownloadTokens,ID);
    }    公共覆盖无效向下()
    {
        DropPrimaryKey(dbo.DownloadTokens);        DropColumn(dbo.DownloadTokens,ID);
        AddColumn(dbo.DownloadTokens,ID,C = GT; c.Int(可空:假的,身份:真));        AddPrimaryKey(dbo.DownloadTokens,ID);
    }
}


  

P.S。为什么你使用 DatabaseGeneratedOption.Computed 属性,而不是
   DatabaseGeneratedOption.Identity


I'm using EF code-first approach and want to change the Id field to guid but can't seem to get past below error.

This is my first migration:

public partial class CreateDownloadToken : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.DownloadTokens",
            c => new
            {
                Id = c.Int(nullable: false, identity: true),
                FileId = c.Int(),
                UserId = c.String(nullable: false, maxLength: 128),
                ValidUntil = c.DateTime(nullable: false),
            })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Files", t => t.FileId)
            .ForeignKey("dbo.Users", t => t.UserId, cascadeDelete: true)
            .Index(t => t.FileId)
            .Index(t => t.UserId);

    }

    public override void Down()
    {
        DropForeignKey("dbo.DownloadTokens", "UserId", "dbo.Users");
        DropForeignKey("dbo.DownloadTokens", "FileId", "dbo.Files");
        DropIndex("dbo.DownloadTokens", new[] { "UserId" });
        DropIndex("dbo.DownloadTokens", new[] { "FileId" });
        DropTable("dbo.DownloadTokens");
    }
}

Later I realized that I need my Id column to be GUID so I changed my model file:

public class DownloadToken
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public Guid Id { get; set; }

    public int? FileId { get; set; }

    [ForeignKey("FileId")]
    public virtual File File { get; set; }

    [Required]
    public string UserId { get; set; }

    [ForeignKey("UserId")]
    public virtual User User { get; set; }

    [Required]
    public DateTime ValidUntil { get; set; }
}

When running Add-Migration ChangeDownloadTokenIdToGuid it generates this file:

public partial class ChangeDownloadTokenIdToGuid : DbMigration
{
    public override void Up()
    {
        DropPrimaryKey("dbo.DownloadTokens");
        AlterColumn("dbo.DownloadTokens", "Id", c => c.Guid(nullable: false));
        AddPrimaryKey("dbo.DownloadTokens", "Id");
    }

    public override void Down()
    {
        DropPrimaryKey("dbo.DownloadTokens");
        AlterColumn("dbo.DownloadTokens", "Id", c => c.Int(nullable: false, identity: true));
        AddPrimaryKey("dbo.DownloadTokens", "Id");
    }
}

Running this file with Update-Database causes this error:

Identity column 'Id' must be of data type int, bigint, smallint, tinyint, or decimal or numeric with a scale of 0, and constrained to be nonnullable.

Any ideas why this might be happening?

解决方案

It was caused because it is impossible to convert previous int type of Id column to Guid type(exactly that try to perform AlterColumn method). Also, error message suggest you, that new type of Id column can be one of type from set: int, bigint, smallint, tinyint, or decimal or numeric with a scale of 0, for them, it is possible to perform conversion from int type.

Solution - simply drop Id column and then recreate it with new Guid type, change migration that way:

public partial class ChangeDownloadTokenIdToGuid : DbMigration
{
    public override void Up()
    {
        DropPrimaryKey("dbo.DownloadTokens");

        DropColumn("dbo.DownloadTokens", "Id");
        AddColumn("dbo.DownloadTokens", "Id", c => c.Guid(nullable: false, identity: true));

        AddPrimaryKey("dbo.DownloadTokens", "Id");
    }

    public override void Down()
    {
        DropPrimaryKey("dbo.DownloadTokens");

        DropColumn("dbo.DownloadTokens", "Id");
        AddColumn("dbo.DownloadTokens", "Id", c => c.Int(nullable: false, identity: true));

        AddPrimaryKey("dbo.DownloadTokens", "Id");
    }
}

P.S. Why you use DatabaseGeneratedOption.Computed attribute, not DatabaseGeneratedOption.Identity?

这篇关于我怎样才能改变一个int ID列与EF迁移GUID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆