在具有EF Core 3.1的SQL Server上生成不可为空的rowversion

问题描述

我们正在尝试使用Fluent API在带有EF Core 3.1的SQL Server上生成不可为空的rowversion列:

public class Person
{
    public int Id { get; set; }
    public byte[] Timestamp { get; set; }
}

public class PersonEntityConfiguration : IEntityTypeConfiguration<Person>
{
    public void Configure(EntityTypeBuilder<Person> builder)
    {
        builder.HasKey(p => p.Id);

        builder.Property(p => p.Timestamp)
            .IsRowVersion()
            .IsRequired();
    }
}

当整个表是新表时,此方法工作正常:

public partial class PersonMigration : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Persons",columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:Identity","1,1"),Timestamp = table.Column<byte[]>(rowVersion: true,nullable: false)
            },constraints: table =>
            {
                table.PrimaryKey("PK_Persons",x => x.Id);
            });
    }
}

但是,有时我们需要将rowversion添加到现有表中。在这种情况下,EF Core会生成无效的迁移:

public partial class PersonTimestampMigration : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<byte[]>(
            name: "Timestamp",table: "Persons",rowVersion: true,nullable: false,defaultValue: new byte[] {  });
    }
}

上面生成的默认值在应用于数据库时将导致异常:

执行DbCommand失败(1ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']

ALTER TABLE [人员]添加[时间戳]行版本非NULL默认值0x;

Microsoft.Data.SqlClient.SqlException(0x80131904):无法在数据类型为timestamp的列上创建默认值。表“人员”,列“时间戳”。
无法创建约束或索引。查看先前的错误。

这是EF Core中的已知错误吗?可以通过从迁移中手动删除defaultValue: new byte[] { }来解决此问题,但是有什么方法可以抑制使用Fluent API生成默认值?

解决方法

这是EF Core中的已知错误吗?

这肯定是错误/缺陷,但可能未知,因为即使在最新的EF Core 5.0预览版中,它也确实在发生。还是已知的,但是优先级较低(对于他们而言)-您必须检查EF Core Issue Tracker

尝试显式添加.HasDefaultValue(null).HasDefaultValueSql(null)-没有帮助,因此唯一的选择是从迁移中手动删除defaultValue: new byte[] { }。这样做的好处是,即使表具有现有记录,这样做也可以正常工作,并且可以成功创建和填充列(这就是EF Core通常为新的必需列添加此类defaultValue参数的原因,但是如我们所见,不应该对ROWVERSION这样做)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...