实体框架代码首先使列不可为空

HBh*_*tia 18 c# sql entity-framework

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

[HiddenInput(DisplayValue = false)]        
public DateTime? PasswordDate { get; set; }
Run Code Online (Sandbox Code Playgroud)

为了使这个不可空的我删除'?' 并从程序包管理器控制台运行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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Update-Database -SourceMigration 201309020721215_PasswordDate
Run Code Online (Sandbox Code Playgroud)

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

请提出解决方案.

mat*_*mmo 13

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

两种解决方案

1)将其更改回可以为空的
2)为没有值的项目提供默认值.

  • 在你的向上迁移中添加`Sql(@"UPDATE [dbo].[CertificateInfoes] SET [PasswordDate] = CURRENT_TIMESTAMP WHERE [PasswordDate] IS NULL");`这将为你填充数据.回去不应该有任何问题. (5认同)
  • 我已经修改了该表并确保数据库中的PasswordDate 列不为空。 (2认同)

som*_*men 8

EF core 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");
    }
}
Run Code Online (Sandbox Code Playgroud)


Ike*_*Ike 5

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

我做的是

  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));
    }
Run Code Online (Sandbox Code Playgroud)