Entity Framework 核心:脚手架以避免更改后数据丢失 Model/Entity

Entity Framework Core: Scaffolding to Avoid Data Loss after to change Model/Entity

我有以下型号:

public class Promotion : BaseModel
{
    [Required]
    public string Description { get; set; }

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

    [Required]
    public double Price { get; set; }
}

创建了更新到数据库的迁移。并且在数据库中插入了一些 促销。但我需要将促销模型更改为:

public class Promotion : BaseModel
{
    [Required]
    public string Description { get; set; }

    [Required]
    public Market Market { get; set; }

    [Required]
    public double Price { get; set; }
}

public class Market : BaseModel
{
    [Required]
    public string Name { get; set; }

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

当我添加一个新的迁移时,我收到了警告:"An operation was scaffolding that may result in the loss of data. Please review the migrations for accuracy."

这是新迁移自动生成的Up方法:

protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Market",
            table: "Promotions");

        migrationBuilder.AddColumn<Guid>(
            name: "MarketId",
            table: "Promotions",
            nullable: false,
            defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));

        migrationBuilder.CreateTable(
            name: "Markets",
            columns: table => new
            {
                Id = table.Column<Guid>(nullable: false),
                Adress = table.Column<string>(nullable: false),
                CreatedAt = table.Column<DateTime>(nullable: false),
                DeletedAt = table.Column<DateTime>(nullable: false),
                Name = table.Column<string>(nullable: false),
                UpdatedAt = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Markets", x => x.Id);
            });

        migrationBuilder.CreateIndex(
            name: "IX_Promotions_MarketId",
            table: "Promotions",
            column: "MarketId");

        migrationBuilder.AddForeignKey(
            name: "FK_Promotions_Markets_MarketId",
            table: "Promotions",
            column: "MarketId",
            principalTable: "Markets",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    }

如何在不丢失数据的情况下更新数据库?

升级生产数据库的安全方法是将其分解为多个步骤:

  1. 添加新的 Market 实体并将其附加到 Promotion 实体 without dropping the existing column
  2. EF 将为您生成迁移 - CREATE TABLE + ADD FOREIGN KEY 语句
  3. 将您的代码设为 update/insert/select 来自 Market tableMarket column 的新值,更喜欢 Market table
  4. 你部署这个。现在,您既有包含数据的旧列,也有新的 table 列,与新数据同步。
  5. 编写数据迁移,将旧值从 Market column 复制到 Market table。 运行它。现在您已将数据移至新的 Market table 并将新数据移至 Market table
  6. 更新您的代码以停止使用旧的 Market column。部署更改
  7. 从您的实体中删除 Market column。 EF 将在删除列的位置生成迁移。部署这个。您现在已经迁移了数据和架构