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

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

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

问题

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

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

  1. public class DbEntity
  2. {
  3. ...
  4. [Timestamp]
  5. public byte[] Timestamp { get; set; }
  6. ...
  7. }

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

  1. [Timestamp] [timestamp] NOT NULL

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

  1. public class DbEntity
  2. {
  3. ...
  4. [Timestamp]
  5. public uint Version { get; set; }
  6. ...
  7. }

不需要在数据库中添加列,因为使用了 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:

  1. public class DbEntity
  2. {
  3. ...
  4. [Timestamp]
  5. public byte[] Timestamp { get; set; }
  6. ...
  7. }

In the database, this field is mapped to:

  1. [Timestamp] [timestamp] NOT NULL

For Postgresql we need something like this:

  1. public class DbEntity
  2. {
  3. ...
  4. [Timestamp]
  5. public uint Version { get; set; }
  6. ...
  7. }

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模型配置,并忽略其他数据库的属性:

  1. public class Blog
  2. {
  3. public int Id { get; set; }
  4. [Timestamp]
  5. public byte[] Timestamp { get; set; }
  6. [Timestamp]
  7. public uint Version { get; set; }
  8. }
  9. // 在模型配置中:
  10. protected override void OnModelCreating(ModelBuilder modelBuilder)
  11. {
  12. if (Database.IsSqlServer())
  13. {
  14. modelBuilder.Entity<Blog>().Ignore(b => b.Version);
  15. }
  16. else if (Database.IsNpgsql())
  17. {
  18. modelBuilder.Entity<Blog>().Ignore(b => b.Timestamp);
  19. }
  20. }
英文:

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:

  1. public class Blog
  2. {
  3. public int Id { get; set; }
  4. [Timestamp]
  5. public byte[] Timestamp { get; set; }
  6. [Timestamp]
  7. public uint Version { get; set; }
  8. }
  9. // In the model configuration:
  10. protected override void OnModelCreating(ModelBuilder modelBuilder)
  11. {
  12. if (Database.IsSqlServer())
  13. {
  14. modelBuilder.Entity&lt;Blog&gt;().Ignore(b =&gt; b.Version);
  15. }
  16. else if (Database.IsNpgsql())
  17. {
  18. modelBuilder.Entity&lt;Blog&gt;().Ignore(b =&gt; b.Timestamp);
  19. }
  20. }

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:

确定