我使用C#EntityFramework和CodeFirst。我也使用迁移(自动和手动迁移)。
我有一个模特 -
public class MyClass
{
public string Key { set; get; }
public string Something { set; get; }
}
我已经拥有一个包含行的数据库。
现在我想改变模型:
一个。改变"关键"列到"名称" (这不是迁移问题,尤其是自动迁移)
湾添加一个新属性 - 一个int" Key"这将是身份(1,2,3 ......)。
如何在不删除现有行的情况下执行 ? (我希望他们获得一个自动ID)
答案 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");
}