实体框架核心:脚手架,避免更改模型/实体后数据丢失

Sér*_*eno 2 scaffolding entity-framework-core asp.net-core

我有以下模型:

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

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

    [Required]
    public double Price { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

当我添加一个新的迁移时,我得到了警报:“某个操作正在脚手架上,可能会导致数据丢失。请检查迁移的准确性。”

这是新迁移自动生成的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);
    }
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*yny 7

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

  1. 添加新Market实体并将其附加到Promotion实体without dropping the existing column
  2. EF将为您带来迁移- CREATE TABLE+ ADD FOREIGN KEY声明
  3. 使您的代码可以同时更新和插入/选择新值,Market table并且Market column更喜欢Market table
  4. 您部署此。现在,您既有包含数据的旧列又有新表,它们正在同步新数据。
  5. 写数据迁移,这将旧值从复制Market columnMarket table。运行。现在,您已将数据移至Market table新数据中Market table
  6. 更新您的代码以停止使用old Market column。部署变更
  7. Market column从您的实体中删除。EF将在列将被删除的位置生成迁移。部署这个。现在,您已迁移了数据和架构