Entity Framework Core在使用PostgreSQL时未更新RowVersion列

6

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

在DbContext的OnModelCreating中有以下配置:

 modelBuilder.Entity<Author>()
    .Property(a => a.RowVersion)
    .IsConcurrencyToken()
    .ValueGeneratedOnAddOrUpdate();

然而,即使在实体更新/创建之后,RowVersion列始终为NULL。
顺便说一下,我正在使用Npgsql库(NuGet)的PostgreSQL。文档中提到,PostgreSQL不支持添加或更新时的计算值
这是造成它无法工作的原因吗?
如果是,我们为什么可以规避这个限制?
此外,我已经进行了测试:
modelBuilder.Entity<Author>().Property<byte[]>("RowVersion")
    .HasColumnName(ShadowPropertiesDb.RowVersion)
    .IsRowVersion();

它导致了相同的问题。


我无法在PostgreSQL上进行测试,但是RowVersion属性的类型是什么?如果它是byte[],您是否尝试过使用.IsRowVersion()而不是.IsConcurrencyToken().ValueGeneratedOnAddOrUpdate() - Ivan Stoev
是的,它是一个byte[]。检查更新后的问题。我已经尝试过了。但没有成功 :( - SuperJMN
2
为了使时间戳/行版本正常工作,数据库引擎应该支持它。据我所知,PostgreSQL不支持自动更新列,因此您必须找到一种方法来手动更新并发标记。也许 这个链接 可以给您提供一些线索。 - Gert Arnold
据我所知,PostgreSQL在行版本控制方面使用了不同的类型,而不是byte[]。 - Smit
你在使用EF时无法在PostgreSQL中实现乐观并发和并发令牌,但是你可以使用modelBuilder.Entity<MyEntity>().ForNpgsqlUseXminAsConcurrencyToken();。我使用自己的计数器列,在调用savechanges通用上下文方法时更新每个实体。 - Janne Harju
1个回答

8
在PostgreSQL中,RowVersion被预定义为名为“xmin”的列。
示例属性(仅适用于Npgsql):
[ConcurrencyCheck]
[Column("xmin",TypeName = "xid")]
public long RowVersion { get; set; }

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

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

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

步骤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);

================ 适用于多种数据库类型 =================

属性:

[ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public byte[] RowVersion { get; set; }

在 "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);
}

这成功地防止了多用户冲突,但是不允许我添加新对象:PostgresException: 42703:关系“Author”的列“xmin”不存在 - halllo
builder.Entity<Author>() .Property(_ => _.RowVersion) .HasColumnName("xmin") .HasColumnType("xid") .HasConversion(converter) .ValueGeneratedOnAddOrUpdate() .IsConcurrencyToken(); - T. Czubaszek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接