2

私は、Oracle バックエンドと MS SQL Server バックエンドの間で使用される EF コードの最初の POCO を構築しています。どちらのデータベース バックエンドでも動作する 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();

したがって、タイムスタンプは 8 バイトであるため、データ型を long に変更できるのではないかと最初に推測しましたが、SqlServer はマッピングが気に入らなかったのです。

次に推測するのは、Timestamp と Ora_RowScn をあきらめて、独自の Optimistic Concurrency プロパティを作成することです。SqlとOracleの両方で機能する幸せなモデルを持つ方法を知っていますか? ありがとう。

4

1 に答える 1

1

これが私が問題を解決した方法です。[Timestamp] 属性を取り除きました。次に、リポジトリ用に 2 つのアセンブリも作成しました。1 つは Oracle 用で、もう 1 つは 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 に答える