Zarówno w EF6, jak i EF-core, pracując z Sql Server, musisz użyć tego mapowania:
modelBuilder.Entity<Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not: IsConcurrencyToken
IsConcurrencyToken konfiguruje właściwość jako token współbieżności, ale (gdy używa go dla byte[]
właściwość)
- typ danych to
varbinary(max)
- jego wartość to zawsze
null
jeśli go nie zainicjujesz - jego wartość nie jest automatycznie zwiększana, gdy rekord jest aktualizowany.
IsRowVersion z drugiej strony
- ma typ danych
rowversion
(na serwerze Sql lubtimestamp
we wcześniejszych wersjach), więc - jego wartość nigdy nie jest pusta i
- jego wartość jest zawsze automatycznie zwiększana, gdy rekord jest aktualizowany.
- i automatycznie konfiguruje właściwość jako optymistyczny token współbieżności.
Teraz, gdy aktualizujesz Car
zobaczysz dwie instrukcje dotyczące aktualizacji:
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 ...
Pierwsza instrukcja niczego nie aktualizuje, ale zwiększa wersję wiersza i zgłosi wyjątek współbieżności, jeśli wersja wiersza została zmieniona pomiędzy.
[System.ComponentModel.DataAnnotations.Schema.Timestamp]
atrybut jest odpowiednikiem adnotacji danych IsRowVersion()
:
[Timestamp]
public byte[] RowVersion { get; set; }