实体框架核心 RowVersion 列未使用 PostgreSQL 更新

Sup*_*JMN 4 c# postgresql concurrency entity-framework entity-framework-core

我为我的实体设置了一个 RowVersion 列,但它似乎没有在创建或更新时存储任何内容。

它在 DbContext 中有这个配置OnModelCreating

 modelBuilder.Entity<Author>()
    .Property(a => a.RowVersion)
    .IsConcurrencyToken()
    .ValueGeneratedOnAddOrUpdate();
Run Code Online (Sandbox Code Playgroud)

但是,RowVersion 列始终为 NULL,即使在实体更新/创建之后也是如此。

顺便说一下,我将 PostgreSQL 与 Npgsql 库 (NuGet) 一起使用。在文档中,它说PostgreSQL 不支持添加或更新时的计算值

这是它不起作用的原因吗?

如果是这样,我们为什么要绕过这个限制?

另外,我已经测试过:

modelBuilder.Entity<Author>().Property<byte[]>("RowVersion")
    .HasColumnName(ShadowPropertiesDb.RowVersion)
    .IsRowVersion();
Run Code Online (Sandbox Code Playgroud)

它导致同样的问题。

小智 5

在 PostgreSQL 中,RowVersion 被预定义为名为“xmin”的列。

示例属性(仅适用于 Npgsql):

[ConcurrencyCheck]
[Column("xmin",TypeName = "xid")]
public long RowVersion { get; set; }
Run Code Online (Sandbox Code Playgroud)

如果您希望属性为 byte[] 类型:

第 1 步:将属性类型更改为 byte[]

[ConcurrencyCheck]
[Column("xmin",TypeName = "xid")]
public byte[] RowVersion { get; set; }
Run Code Online (Sandbox Code Playgroud)

第 2 步:在“OnModelCreating(ModelBuilder builder)”中添加转换器

var converter = new ValueConverter<byte[], long>(
     v => BitConverter.ToInt64(v, 0), 
     v => BitConverter.GetBytes(v));

builder.Entity<Author>()
   .Property(_ => _.RowVersion)
   .HasConversion(converter);
Run Code Online (Sandbox Code Playgroud)

================ 对于许多数据库类型 ================

财产:

[ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public byte[] RowVersion { get; set; }
Run Code Online (Sandbox Code Playgroud)

在“OnModelCreating(ModelBuilder builder)”中:

if (Database.IsNpgsql())
{
    var converter = new ValueConverter<byte[], long>(
        v => BitConverter.ToInt64(v, 0),
        v => BitConverter.GetBytes(v));

    builder.Entity<Author>()
            .Property(_ => _.RowVersion)
            .HasColumnName("xmin")
            .HasColumnType("xid")
            .HasConversion(converter);
}
Run Code Online (Sandbox Code Playgroud)