在实体框架迁移中切换到具有不同类型的人造密钥 [英] Switching to artificial key with different type in Entity Framework Migrations

查看:84
本文介绍了在实体框架迁移中切换到具有不同类型的人造密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个实体框架代码第一个项目,以前我有一个类的字段叫做Id,这是一个字符串类型并使用哈希。

I'm working on an Entity Framework Code First project where, previously, I had a class with a field called "Id" that was a string type and using the hash.

这样做指定:

[Key]
public string Id { get; set; }

这不再是我需要的,因为更新我现在可以重复的值,所以我想更改它看起来像这样:

That's no longer what I need because with updates I can now have duplicate values, so I want to change it to look like this:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

[Required]
[Index]
public string Hash { get; set; } //This represents what used to be Id

我遇到了麻烦,去挖掘,发现< a href =https://entityframework.codeplex.com/workitem/776 =nofollowtitle =迁移:更改主键的数据类型中断迁移[FixedIn6.1.0-alpha1] [AffectedLastRTM]一个错误报告表明这可以在Entity Framework 6.1.0中工作,所以我已经更新了,但是它仍然没有为我工作。我将一些SQL手动输入到迁移文件中,以便将Hash列设置为Id值,然后才能更新外部键,否则更新失败,因为无法从字母数字中移除nvarchar到int。当然,我想要的是插入与旧哈希对应的整数ID。

I ran into some trouble and went digging and found a bug report suggesting that this would work in Entity Framework 6.1.0, so I've updated, but it's still not really working for me. I hand-entered some SQL into the migration file to set the Hash column to the Id value before it gets blown away, but the update fails when it goes to update the foreign keys because it can't figure out how to go from an alphanumeric nvarchar to an int. Of course, what I'd like it to do is insert the integer ID that corresponds to the old hash.

有没有一些非破坏性的方式可以实现这个? p>

Is there some nondestructive way I can achieve this?

推荐答案

嗯,我有点犹豫,发布解决方案,我最终去,因为感觉像一个黑客,但由于我真的不希望任何其他答案在这一点上,这里是。

Well, I was a little bit hesitant to post the solution I ended up going with, because it feels like a bit of a hack, but since I don't really expect any other answers at this point, here it is.

我最终用这种方法手动编辑迁移。实质上,我放弃了约束,做一个更新查询以得到一个nvarchar表示的整数,然后转换为一个int并再次添加约束。

I ended up hand-editing the migration with this method. Essentially, I'm dropping the constraints, doing an update query to get an nvarchar representation of the integer key, then converting to an int and adding the constraints again.

public override void Up()
  {
    DropIndex("dbo.ValueSetElements", new[] { "Parent_Id" });
    DropIndex("dbo.SectionElements", new[] { "Choices_Id" });
    DropForeignKey("dbo.ValueSetElements", "Parent_Id", "dbo.ValueSets");
    DropForeignKey("dbo.SectionElements", "Choices_Id", "dbo.ValueSets");
    DropPrimaryKey(ValueSetTable, "PK_dbo.ValueSets");
    RenameColumn(ValueSetTable, "Id", "Hash");
    AddColumn(ValueSetTable, "Id", c => c.Int(nullable: false, identity: true, name: "Id"));
    AddPrimaryKey(ValueSetTable, "Id");
    CreateIndex(ValueSetTable, "Hash");
    Sql("UPDATE dbo.SectionElements SET Choices_Id = CONVERT(nvarchar(10), (SELECT Id FROM dbo.ValueSets WHERE dbo.ValueSets.Hash = dbo.SectionElements.Choices_Id))");
    AlterColumn("dbo.SectionElements", "Choices_Id", c => c.Int());
    AddForeignKey("dbo.SectionElements", "Choices_Id", "dbo.ValueSets", "Id");
    CreateIndex("dbo.SectionElements", "Choices_Id");
    Sql("ALTER TABLE dbo.ValueSetElements DROP CONSTRAINT [DF__ValueSetE__Paren__0F63164F]");
    Sql("UPDATE dbo.ValueSetElements SET Parent_Id = CONVERT(nvarchar(10), (SELECT Id FROM dbo.ValueSets WHERE dbo.ValueSets.Hash = dbo.ValueSetElements.Parent_Id))");
    AlterColumn("dbo.ValueSetElements", "Parent_Id", c => c.Int(nullable: false));
    AddForeignKey("dbo.ValueSetElements", "Parent_Id", ValueSetTable, "Id", cascadeDelete: true);
    CreateIndex("dbo.ValueSetElements", "Parent_Id");
  }

这篇关于在实体框架迁移中切换到具有不同类型的人造密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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