c# - 使用 EF Code First Migration 将新的必填字段添加到其中一个表中

标签 c# entity-framework ef-code-first entity-framework-migrations

我正在使用 EF Code First Migration。我已经有很多关于生产数据库的数据,我想引入一个不可为空的字段。怎么可能?

目前它抛出一个错误:

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 的列,然后再删除默认值。这允许您在迁移期间将所有行设置为相同的值,同时仍然需要您在添加新行时手动指定值。这种方法据说不适用于旧版本的 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");
}

关于c# - 使用 EF Code First Migration 将新的必填字段添加到其中一个表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27274103/

相关文章:

c# - 如何首先在 EF 代码中处理一个数据库在多个数据库上下文中使用的一个类?

c# - 在 Entity Framework 6 中使用 SqlQuery<Dictionary<string, string>>

c# - EF,更新不起作用,它表示自加载实体以来实体可能已被修改或删除。

entity-framework - Entity Framework CF 可以存储 'object type' 值吗?

c# - 从 Cosmos 中删除数据时出现分区键错误

entity-framework - 如何在 Entity Framework (EF6) 中为模型优先实体添加索引?

c# - Entity Framework 代码首先从父级中删除一到零/一个子级

c# - 如何让 XAML Button Tapped 事件触发所有点击?

c# - Settings.settings 中是否允许可空的 int 类型?

c# - 在 TabContainer 中定位选项卡