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
nulljeś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 lubtimestampwe 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; }