Oracle 和 T-SQL 之间的实体框架中的乐观并发

本文关键字:乐观 并发 框架 实体 T-SQL 之间 Oracle | 更新日期: 2023-09-27 18:35:34

我正在构建EF Code优先POCO,它将在Oracle后端和MS SQL Server后端之间使用。我在寻找正确的方法来处理适用于任一数据库后端的 Timestamp 属性时遇到问题。

MS SQL Server会让我使用这样的公共属性:

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

然后在流畅的映射中,它看起来像这样

map.Property(p => p.Timestamp).IsRowVersion();

但是,Oracle 会让我将我的公共属性类型更改为:

public int Timestamp {get;set;}

然后在流畅的映射中,它看起来像这样

map.Property(p => p.Timestamp).HasColumnName("ORA_ROWSCN").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed).IsConcurrencyToken();

所以我的第一个猜测是也许我可以将数据类型更改为 long,因为时间戳是八个字节,但 SqlServer 不喜欢映射。

我的下一个猜测是放弃时间戳和Ora_RowScn,并组成我自己的乐观并发属性。任何建议或知道是否有一种方法可以在SQL和Oracle之间工作? 谢谢。

Oracle 和 T-SQL 之间的实体框架中的乐观并发

这就是我解决问题的方式。我删除了 [时间戳] 属性。然后,我还为我的存储库创建了两个程序集,一个用于 Oracle,另一个用于 MSSQL。然后我的基本模型看起来像这样。

[DataContract]
    public abstract class DomainBase
    {
        /// <summary>
        /// Gets or sets the id.
        /// </summary>
        [DataMember]
        [Key]
        public long Id { get; set; }

        private byte[] _timestamp=new Guid().ToByteArray();
        /// <summary>
        /// Gets or sets the timestamp.
        /// </summary>
        [DataMember]
        public byte[] Timestamp { get { return _timestamp; }
            set { _timestamp = value;
            if (_timestamp != null && _signature != Convert.ToBase64String(_timestamp))
                    _signature = Convert.ToBase64String(_timestamp);
            }
        }
        private string _signature = Convert.ToBase64String(new Guid().ToByteArray());
        /// <summary>
        /// Gets the signature.
        /// </summary>
        [DataMember]
        public string Signature
        {
            get { return _signature ?? (Timestamp != null ? _signature = Convert.ToBase64String(Timestamp) : null); }
            protected set { _signature = value;
                if ((_timestamp == null && !String.IsNullOrWhiteSpace(_signature)) ||
                    (_timestamp != null && !String.IsNullOrWhiteSpace(_signature) && Convert.ToBase64String(_timestamp) != _signature))
                    _timestamp = Convert.FromBase64String(value);
            }
        }
        /// <summary>
        /// Gets a value indicating whether has signature.
        /// </summary>
        public bool HasSignature
        {
            get { return Timestamp != null; }
        }
    }

然后这就是我处理每个流畅设置中的映射的方式。

对于 MSSQL 服务器。

Property(p => p.Timestamp).HasColumnType("timestamp").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed).IsRowVersion();
            Ignore(p => p.Signature);

对于甲骨文

Ignore(p => p.Timestamp);
            Property(p => p.Signature).HasColumnName("Timestamp").IsConcurrencyToken();