22

我首先在我的项目中使用 EF 代码。我的 DataModel 中有以下代码

[HiddenInput(DisplayValue = false)]        
public DateTime? PasswordDate { get; set; }

为了使这个不可为空,我删除了“?” 并从包管理器控制台运行 Add-Migration 命令。生成了以下迁移文件。

  public partial class PasswordDate : DbMigration
{
    public override void Up()
    {
        AlterColumn("dbo.CertificateInfoes", "PasswordDate", c => c.DateTime(nullable: false));
    }

    public override void Down()
    {
        AlterColumn("dbo.CertificateInfoes", "PasswordDate", c => c.DateTime());
    }
}

但是当我运行 Update-Database 命令时:

Update-Database -SourceMigration 201309020721215_PasswordDate

我收到以下错误:无法将值 NULL 插入列“PasswordDate”,表“”;列不允许空值。更新失败。该语句已终止。

请提出解决方案。

4

3 回答 3

17

那是因为您允许NULL该列中的值,然后尝试使其不可为空。随后它将尝试将您现有的数据迁移到新的不可为空的列中,这将中断,因为您已经NULL在其中有值。

两种解决方案:

1) 将其改回可为空
2) 为没有值的项目赋予默认值。

于 2013-09-02T08:50:03.080 回答
7

如果没有为该列提供默认值,则无法直接将不可为空的列添加到表中包含历史数据的表中。

我所做的是

  1. 将列添加为可为空。
  2. 提供一个 sql 脚本来填充这个新添加的列。
  3. 更改要制作的列是不可为空的。

代码示例(使用 postgres 数据库):

 public override void Up()
    {            
        AddColumn("public.YourTableName", "YourColumnName", c => c.Int(nullable: true));
        Sql(@"UPDATE ""public"".""YourTableName""
              SET ""YourColumnName"" = Value you want to set
            ");

        AlterColumn("public.YourTableName", "YourColumnName", c => c.Int(nullable: false));
    }
于 2020-05-30T23:22:43.347 回答
1

EF 核心 6 中的另一种方法是更改​​添加列指定默认值的迁移脚本。然后,您可以稍后再次删除此默认值。

public partial class AddOrderSource : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // Add the column with a default value, then drop the default value.
        // This creates a non-nullable column without the migration failing because of existing data.

        migrationBuilder.AddColumn<int>(
            name: "OrderSource",
            table: "Orders",
            type: "int",
            nullable: false,
            defaultValue: 1); // Sample default value

        migrationBuilder.AlterColumn<int>(
            name: "OrderSource", 
            table: "Orders",
            oldDefaultValue: 1,
            defaultValue: null
        );
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "OrderSource",
            table: "Orders");
    }
}
于 2021-12-29T17:48:55.593 回答