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);
}
如何在不丢失数据的情况下更新数据库?
升级生产数据库的安全方法是将其分解为多个步骤:
- 添加新的
Market
实体并将其附加到 Promotion
实体 without dropping the existing column
- EF 将为您生成迁移 -
CREATE TABLE
+ ADD FOREIGN KEY
语句
- 将您的代码设为 update/insert/select 来自
Market table
和 Market column
的新值,更喜欢 Market table
- 你部署这个。现在,您既有包含数据的旧列,也有新的 table 列,与新数据同步。
- 编写数据迁移,将旧值从
Market column
复制到 Market table
。 运行它。现在您已将数据移至新的 Market table
并将新数据移至 Market table
- 更新您的代码以停止使用旧的
Market column
。部署更改
- 从您的实体中删除
Market column
。 EF 将在删除列的位置生成迁移。部署这个。您现在已经迁移了数据和架构
我有以下型号:
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);
}
如何在不丢失数据的情况下更新数据库?
升级生产数据库的安全方法是将其分解为多个步骤:
- 添加新的
Market
实体并将其附加到Promotion
实体without dropping the existing column
- EF 将为您生成迁移 -
CREATE TABLE
+ADD FOREIGN KEY
语句 - 将您的代码设为 update/insert/select 来自
Market table
和Market column
的新值,更喜欢Market table
- 你部署这个。现在,您既有包含数据的旧列,也有新的 table 列,与新数据同步。
- 编写数据迁移,将旧值从
Market column
复制到Market table
。 运行它。现在您已将数据移至新的Market table
并将新数据移至Market table
- 更新您的代码以停止使用旧的
Market column
。部署更改 - 从您的实体中删除
Market column
。 EF 将在删除列的位置生成迁移。部署这个。您现在已经迁移了数据和架构