将新的必填字段添加到具有 EF 代码优先迁移的表之一
本文关键字:迁移 代码 EF 字段 添加 | 更新日期: 2023-09-27 18:33:01
我正在使用EF Code First Migration。我已经有很多关于生产 Db 的数据,我想引入一个不可为空的字段。怎么可能?
当前它抛出一个错误:
The column cannot contain null values. [ Column name = Test,Table name = 'MyTable']
我通常为此使用的策略是首先将新列作为可选列引入,填充它,然后将其设置为必需列。实际上,您可以通过为每个步骤进行单独的迁移来执行单独的迁移步骤,或者手动更改自动生成的迁移代码以使更改全部发生在一次迁移中。我将介绍如何使用单个迁移。
如果添加新的[Required]
字段,自动生成的迁移可能如下所示,如果dbo.MyTable
其中包含数据,则会失败:
public override void Up()
{
AddColumn("dbo.MyTable", "MyColumn", c => c.String(nullable: false));
}
public override void Down()
{
DropColumn("dbo.MyTable", "MyColumn");
}
您可以编辑迁移以最初将列添加为可选列,预填充它,然后将其标记为必需。您可以使用Sql()
来执行预填充。根据您的数据,您可能希望根据其他列甚至另一个表计算新列的值,您可以通过编写适当的 SQL 来做到这一点。
public override void Up()
{
AddColumn("dbo.MyTable", "MyColumn", c => c.String());
Sql("UPDATE dbo.MyTable SET MyColumn = COALESCE(SomeOtherColumn, 'My Fallback Value')");
AlterColumn("dbo.MyTable", "MyColumn", c => c.String(nullable: false));
}
public override void Down()
{
DropColumn("dbo.MyTable", "MyColumn");
}
如果只想在所有行上设置相同的值,则可以跳过Sql()
步骤,并根据需要添加列,并在删除defaultValue
之前使用defaultValue
。这允许您在迁移期间将所有行设置为相同的值,同时仍要求您在添加新行时手动指定该值。这种方法应该不适用于旧版本的 EF。我不确定需要哪个版本的 EF,但它至少应该适用于现代版本(≥6.2(:
public override void Up()
{
AddColumn("dbo.MyTable", "MyColumn", c => c.String(defaultValue: "Some Value", nullable: false));
}
public override void Down()
{
DropColumn("dbo.MyTable", "MyColumn");
}
您可以在迁移文件中添加一个默认值,如下所示:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "MyColumn",
table: "dbo.MyTable",
nullable: false,
defaultValue: "");
}
如果列是布尔值,那么您只需根据需要输入默认值 false 或 true。
在 EFCore 3.1 中,您只需添加必需的属性,它就会自动设置默认值
布尔值默认为 false
[Required]
public Boolean myField {get;set;}
整数默认值为 0
[Required]
public int myField {get;set;}
字符串默认为 ">
[Required]
public string myField {get;set;}