我的表格有一个文本列,我想更改为整数。现有文本列包含可转换为整数的值。我不想更改列名称。
如何首先使用代码安全地执行此操作而不丢失数据?
一种选择是创建一个新的临时列。复制值。然后删除旧列并重命名新列。但我只是不太确定实体框架将决定如何处理这些更改。
所以,我只是将列定义更改为:
[Display(Name = "Bill of Lading")]
[Required]
[StringLength(80)]
public string BillOfLading { get; set; }
致:
[Display(Name = "Bill of Lading")]
public int BillOfLading { get; set; }
我修补了我的代码,以便它可以使用新类型进行编译,并且添加了一个迁移,如下所示:
public partial class TransloadingDetailBillOfLadingToInt : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "BillOfLading",
table: "TransloadingDetails",
type: "int",
nullable: false,
oldClrType: typeof(string),
oldType: "nvarchar(80)",
oldMaxLength: 80);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "BillOfLading",
table: "TransloadingDetails",
type: "nvarchar(80)",
maxLength: 80,
nullable: false,
oldClrType: typeof(int),
oldType: "int");
}
}
我能够在我们拥有的较小的演示数据库上运行
update-database
。在我的第一次尝试中,我有一个无法转换的列值。在这种情况下,我收到了一个错误,但没有丢失任何数据。好兆头!
更正数据后,我再次运行它,文本列已转换为整数。所有现有数据均已正确转换。然后我的主数据库上也有同样的事情。
因此,至少在将文本列转换为整数列(可以转换数据)的情况下,这就像您希望的那样工作。
这样做!!
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("UPDATE \"Products\" SET \"Status\" = '0' WHERE \"Status\" IS NULL OR \"Status\" !~ '^[0-9]+$'");
migrationBuilder.Sql("ALTER TABLE \"Products\" ALTER COLUMN \"Status\" TYPE integer USING (\"Status\"::integer)");
migrationBuilder.AlterColumn<int>(
name: "Status",
table: "Products",
type: "integer",
nullable: false,
oldClrType: typeof(string),
oldType: "text");
}