如何将字符串键更改为int

时间:2015-01-13 08:15:24

标签: c# entity-framework key code-first ef-migrations

我使用C#EntityFramework和CodeFirst。我也使用迁移(自动和手动迁移)。

我有一个模特 -

public class MyClass
{
    public string Key { set; get; }
    public string Something { set; get; } 
}

我已经拥有一个包含行的数据库。

现在我想改变模型:

一个。改变"关键"列到"名称" (这不是迁移问题,尤其是自动迁移)

添加一个新属性 - 一个int" Key"这将是身份(1,2,3 ......)。

如何在不删除现有行的情况下执行 ? (我希望他们获得一个自动ID)

2 个答案:

答案 0 :(得分:0)

据我所知,你不能在不删除现有条目的情况下改变数据库的类型模式。

鉴于上述情况,我将创建一个新表,并且表中的foreach实体将其提交到新表,并将字符串键转换为整数(假设它们都是字符串格式的有效整数)。

须藤代码:

list<Entity> Entities = new list<Entity>(); //put all the database entities in here.
List<AlteredEntity> AlteredEntities = new List<AlteredEntity>(); // for the new table

foreach (Entity r in Entities)
{
    AlteredEntity TempEnt = new AlteredEntity();
    TempEnt.Key = Convert.toint32(r.Key);
    TempEnt.Something = r.Something;
    AlteredEntities.Add(TempEnt);
}
// iterate through AlteredEntities to input into the database

我会这样做,这样如果任何实体丢失或数据库中断,您仍然保持原始记录不变。一旦您确认原始数据已完全转移,您可以删除旧表并切换新表。

答案 1 :(得分:0)

我决定对此进行测试。我从这个类开始,添加了一个迁移,更新了数据库,并插入了一些数据:

public class MyClass
{
    [Key]//Added this to get rid of the error: 
         //EntityType 'Class1' has no key defined. Define the key for this EntityType.
    public string Key { set; get; }
    public string Something { set; get; } 
}

然后我将其更改为此并进行第二次迁移。

public class MyClass
{
    public int ID { get; set; }
    public string Key { set; get; }
    public string Something { set; get; } 
}

以下是生成的迁移。默认情况下,EF会将名为“ID”的整数列作为密钥 - 标识为true:

public override void Up()
{
    DropPrimaryKey("dbo.MyClasses");
    AddColumn("dbo.MyClasses", "ID", c => c.Int(nullable: false, identity: true));
    AlterColumn("dbo.MyClasses", "Key", c => c.String());
    AddPrimaryKey("dbo.MyClasses", "ID");
}

然后我将Key更改为Name并进行了另一次迁移。但是为了避免丢失数据,我在删除列之前添加了一些sql:

public override void Up()
{
    AddColumn("dbo.MyClasses", "Name", c => c.String());
    Sql("UPDATE dbo.MyClasses SET Name = [Key]"); //Manually added to migration
    DropColumn("dbo.MyClasses", "Key");
}

public override void Down()
{
    AddColumn("dbo.MyClasses", "Key", c => c.String());
    Sql("UPDATE dbo.MyClasses SET [Key] = Name"); //Manually added to migration
    DropColumn("dbo.MyClasses", "Name");
}