如何编写适用于SQL Server和PostgreSQL的通用乐观并发时间戳列。

huangapple go评论69阅读模式
英文:

How to write universal optimistic concurrency Timestamp column that works with SQL Server and with Postgresql

问题

我们需要支持两种数据库:SQL Server 和 Postgresql。对于乐观并发,我们使用了[Timestamp]列。

对于 SQL Server,这段代码有效:

public class DbEntity
{
	...
	[Timestamp]
	public byte[] Timestamp { get; set; }
	...
}

在数据库中,该字段映射为:

[Timestamp] [timestamp] NOT NULL

对于 Postgresql,我们需要类似这样的内容:

public class DbEntity
{
	...
	[Timestamp]
    public uint Version { get; set; }
	...
}

不需要在数据库中添加列,因为使用了 xmin 系统列 - 参考链接:https://www.npgsql.org/efcore/modeling/concurrency.html?tabs=data-annotations

是否可能编写通用的实体,使其能在两种数据库中都有效?我希望只需编写一次,而不需要在源代码控制中维护两个应用程序或两个分支。

英文:

We need to support both databases: SQL Server and Postgresql. For optimistic concurrency we use a [Timestamp] column.

For SQL Server this code works:

public class DbEntity
{
	...
	[Timestamp]
	public byte[] Timestamp { get; set; }
	...
}

In the database, this field is mapped to:

[Timestamp] [timestamp] NOT NULL

For Postgresql we need something like this:

public class DbEntity
{
	...
	[Timestamp]
    public uint Version { get; set; }
	...
}

without column in database, because xmin system column used - https://www.npgsql.org/efcore/modeling/concurrency.html?tabs=data-annotations

It is possible to write universal entities that works with both databases? I want to write them once, and do not support 2 applications or 2 branches in source control.

答案1

得分: 2

你可以在你的.NET类型上同时拥有这两个属性,并根据使用的提供程序变化EF模型配置,并忽略其他数据库的属性:

public class Blog
{
    public int Id { get; set; }

    [Timestamp]
    public byte[] Timestamp { get; set; }

    [Timestamp]
    public uint Version { get; set; }
}

// 在模型配置中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (Database.IsSqlServer())
    {
        modelBuilder.Entity<Blog>().Ignore(b => b.Version);
    }
    else if (Database.IsNpgsql())
    {
        modelBuilder.Entity<Blog>().Ignore(b => b.Timestamp);
    }
}
英文:

You can use have both properties on your .NET type and vary the EF model configuration based on the provider being used, and ignore the property for the other databases:

public class Blog
{
    public int Id { get; set; }

    [Timestamp]
    public byte[] Timestamp { get; set; }

    [Timestamp]
    public uint Version { get; set; }
}

// In the model configuration:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (Database.IsSqlServer())
    {
        modelBuilder.Entity&lt;Blog&gt;().Ignore(b =&gt; b.Version);
    }
    else if (Database.IsNpgsql())
    {
        modelBuilder.Entity&lt;Blog&gt;().Ignore(b =&gt; b.Timestamp);
    }
}

huangapple
  • 本文由 发表于 2023年5月18日 00:31:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274297.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定