Timestamp/rowversion 是一个EF Core属性,在每次插入或更新数据行时,数据库会自动为其生成新值。
因此此属性也被视为并发标记,这确保了在你查询行后,如果正在更新的行发生了更改,则会出现异常。可以参考之前的数据库乐观锁介绍。
对于 SQL Server,通常使用 byte [] 属性,该属性将设置为数据库中的 ROWVERSION 列。
代码如下:
public class Blog {
public int BlogId {get; set; }
public string Url { get; set; }
[Timestamp]
public byte[] Timestamp { get; set; }
}
复制代码
当然也可以是在 OnModelCreating 内设置
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(p => p.Timestamp)
.IsRowVersion();
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public byte[] Timestamp { get; set; }
}
复制代码
注意: 如果需要映射到ulong,需要使用转换函数HasConversion:
modelBuilder.Entity<Blog>()
.Property(p => p.Timestamp)
.IsRowVersion().HasConversion<int>();
复制代码
在SQL Server里,RowVersion是一种自增的只用于定义数据表的列类型,其值占用的大小是固定的8个字节,是SQL Server数据库自动生成的、数据库级别唯一的、二进制数字,使用binary(8)存储。
每个数据库都有一个自增的计数器,该计数器是Database RowVersion,在用户对有RowVersion 字段的数据表执行插入或修改命令时,该计数器就会增加。
可以使用全局变量 @@DBTS 进行查询其值, 该值在整个数据库中是唯一的、递增的,不可回滚的。
select @@DBTS;
复制代码
当然对于一个数据表,最多有一个RowVersion 字段。
PostgreSQL中具有Timestamp类型,其是日期时间字段,并不能直接转为SQL Server的RowVersion/Timestamp类型。
与RowVersion行为最为接近的列类型,是PostgreSQL中用于MVCC管理的 xmin隐藏列,这个列每个表系统都会自动建立,因此无需增加。当然还有其他隐藏列,比如xmax,xmin表示插入该表的事务号,xmax表示删除该表的事务号。
唯一的瑕疵是使用xmin作为行版本标识不能区别同一个事务内的两次、多次修改。当然事务内的第一次修改对其他事务不可见,唯一能看见它的只有修改这一行的事务自己。
在EF中我们可以采用下列实体定义,以便支持xmin列。
[Timestamp]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Column("xmin", TypeName = "xid")]
public uint Rowversion { get; set; }
复制代码
当然,也可以在OnConfiguring里写语句。
builder.Entity<EmailAddressValidation>()
.Property(e => e.RowVersion).IsRowVersion().HasColumnName("xmin").HasConversion<int>();
复制代码
检查数据库数据,OK,是那么的回事了。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69999831/viewspace-3162387/ ,如需转载,请注明出处,否则将追究法律责任。