4

我有一个带有字符串属性的实体,我需要将其外部化到另一组实体:

public class MyEntity
{
    public int Id { get; set; }
    public string FavoriteColor { get; set; }
}

我想将其更改为:

public class MyEntity
{
    public int Id { get; set; }
    public Color FavoriteColor { get; set; }
    public int FavoriteColorId { get; set; }
}

public class Color
{
    public int Id { get; set; }
    public string Name { get; set; }
}

如果我创建迁移,它会在 db 中创建新的“Color”表,然后将新列添加到“MyEntity”。如何确保不会丢失“MyEntity”上作为字符串存在的所有数据?我尝试在迁移中加载 DbContext 以根据“MyEntity”中的字符串数据创建新的“Color”实体,但它存在问题,因为它检测到模型与当前模式不同步。

4

2 回答 2

2

在您的项目中,转到包管理器窗口并:

  1. 启用迁移:Enable-Migrations
  2. 创建迁移:Add-Migration Initial
  3. 创建升级/降级脚本:Update-Database

在您的情况下,您要添加一个新表 ( Color) 和两个新列。

您有理由,如果您启动您的网站,FavoriteColor包括其数据在内的将被删除。

你可以做什么:

在包管理器控制台中运行时Add-Migration Initial将创建一个新脚本(C# 文件)。正如您在此文件中看到的,删除了一列,添加了 2 列,并创建了 1 个表。

确保在列之前创建表,用数据填充它,使用基于旧列的现有数据创建 2 列,然后删除该列。

另一种方法(可能更好)是在几个迁移脚本中执行此操作,您也可以使用该Seed()方法填充数据。

于 2013-09-07T10:43:45.063 回答
1

如果您使用 创建迁移Add-Migration,迁移文件将是脚手架,如:

Up()
{
    CreateTable("dbo.Color"...);
    DropColumn("FavoriteColor");
    AddColumn("FavoriteColor", c=>Int(nullable: false));

// Some other code
}

您也可以更改此文件以实现数据迁移

Up()
{
    CreateTable("dbo.Color"...);
    AddColumn("FavoriteColor", c=>Int(nullable: false));

    Sql("INSERT INTO dbo.Color (Id, Name) SELECT DISTINCT FavoriteColor FROM dbo.MyEntity");

    // And the other data corrections here using Sql() method.

    DropColumn("FavoriteColor");

// Some other code
}
于 2015-11-04T10:37:25.150 回答