You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写适配SQL Server与PostgreSQL的通用乐观并发Timestamp列

适配SQL Server和PostgreSQL的通用乐观并发实体类实现

可以通过EF Core的Fluent API配置+运行时数据库类型判断实现单一实体类适配两种数据库,无需维护多个分支。核心思路是在实体类中定义统一的版本属性,再根据当前使用的数据库提供程序,动态配置该属性的映射规则:

1. 定义通用实体类

选择ulong作为版本属性的类型(兼容SQL Server的8字节rowversion和PostgreSQL的xmin系统列):

public class DbEntity
{
    // 主键及其他业务属性
    public int Id { get; set; }
    public string Name { get; set; }

    // 统一的乐观并发版本属性
    public ulong Version { get; set; }
}

2. 在DbContext中配置数据库专属映射

重写OnModelCreating方法,根据数据库提供程序类型分别配置:

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public DbSet<DbEntity> DbEntities { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 根据环境配置对应数据库的连接字符串
        // optionsBuilder.UseSqlServer("SQL_SERVER_CONN_STRING");
        // 或 optionsBuilder.UseNpgsql("POSTGRESQL_CONN_STRING");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var entityConfig = modelBuilder.Entity<DbEntity>();

        // 判断当前数据库提供程序
        if (Database.ProviderName == "Microsoft.EntityFrameworkCore.SqlServer")
        {
            // SQL Server:将ulong转换为byte[]映射到timestamp列,自动生成并作为并发令牌
            entityConfig.Property(e => e.Version)
                .IsRowVersion()
                .HasConversion(
                    ulongValue => BitConverter.GetBytes(ulongValue),
                    byteArray => BitConverter.ToUInt64(byteArray, 0))
                .HasColumnType("timestamp");
        }
        else if (Database.ProviderName == "Npgsql.EntityFrameworkCore.PostgreSQL")
        {
            // PostgreSQL:映射到系统列xmin,自动生成并作为并发令牌
            entityConfig.Property(e => e.Version)
                .HasColumnName("xmin")
                .HasColumnType("xid")
                .ValueGeneratedOnAddOrUpdate()
                .IsConcurrencyToken();
        }
    }
}

关键说明

  • SQL Server端:IsRowVersion()会自动将属性标记为并发令牌,数据库会自动维护timestamp列的递增,无需手动赋值。通过类型转换将ulong与byte[]互转,保证实体类类型统一。
  • PostgreSQL端:直接映射到内置的xmin系统列(该列记录行的版本号,每次更新自动递增),无需手动创建数据库列,ValueGeneratedOnAddOrUpdate()和IsConcurrencyToken()确保EF Core将其用作乐观并发校验。
  • 无需修改实体类代码,仅通过DbContext配置适配不同数据库,同一代码库可直接切换SQL Server/PostgreSQL连接字符串使用。

内容的提问来源于stack exchange,提问作者Alex T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:08:20