2

I am building EF Code first POCOs that'll be used between an Oracle back-end and a MS SQL Server backend. I'm having a problem finding the right way to tackle a Timestamp property that'll work on either database back-end.

MS SQL Server would have me use a common property like this:

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

And then in the fluent mapping it would look like this

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

However Oracle would have me change my common property type to this:

public int Timestamp {get;set;}

And then in the fluent mapping it would look like this

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

So my first guess was maybe I could change the data type to long, since timestamp is eight bytes, but SqlServer didn't like the mapping.

My next guess is to give up on Timestamp and Ora_RowScn and make up my own Optimistic Concurrency property. Any suggestions or know if a way to have a happy model that works between both Sql and Oracle? Thanks.

4

1 回答 1

1

这就是我解决问题的方法。我摆脱了 [Timestamp] 属性。然后我还为我的存储库创建了两个程序集,一个用于 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();
于 2013-12-03T15:30:40.043 回答