EF6とEFコアの両方で、SQL Serverを使用する場合は、次のマッピングを使用する必要があります。
modelBuilder.Entity<Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not: IsConcurrencyToken
IsConcurrencyToken プロパティを同時実行トークンとして構成しますが、(byte[]
に使用する場合 プロパティ)
- データ型は
varbinary(max)
です - その値は常に
null
初期化しない場合 - レコードが更新されても、その値は自動インクリメントされません。
IsRowVersion 一方、
- データ型は
rowversion
(SQL Server、またはtimestamp
以前のバージョンでは)、したがって - その値がnullになることはなく、
- レコードが更新されると、その値は常に自動インクリメントされます。
- そして、プロパティを楽観的同時実行トークンとして自動的に構成します。
Car
を更新すると 2つの更新ステートメントが表示されます:
DECLARE @p int
UPDATE [dbo].[Product]
SET @p = 0
WHERE (([Id] = @0) AND ([Rowversion] = @1))
SELECT [Rowversion]
FROM [dbo].[Product]
WHERE @@ROWCOUNT > 0 AND [Id] = @0
UPDATE [dbo].[Car]
SET ...
最初のステートメントは何も更新しませんが、行バージョンをインクリメントし、行バージョンが途中で変更された場合は同時実行例外をスローします。
[System.ComponentModel.DataAnnotations.Schema.Timestamp]
属性は、IsRowVersion()
と同等のデータ注釈です。 :
[Timestamp]
public byte[] RowVersion { get; set; }