Tanto en EF6 como en EF-core, cuando trabaje con Sql Server, debe usar esta asignación:
modelBuilder.Entity<Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not: IsConcurrencyToken
Es un token de concurrencia configura una propiedad como token de concurrencia, pero (cuando se usa para un byte[]
propiedad)
- el tipo de datos es
varbinary(max)
- su valor siempre es
null
si no lo inicializas - su valor no se incrementa automáticamente cuando se actualiza un registro.
VersiónIsRow por otro lado,
- tiene el tipo de datos
rowversion
(en Sql Server, otimestamp
en versiones anteriores), por lo que - su valor nunca es nulo, y
- su valor siempre se incrementa automáticamente cuando se actualiza un registro.
- y configura automáticamente la propiedad para que sea un token de concurrencia optimista.
Ahora cuando actualizas un Car
verá dos declaraciones de actualización:
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 ...
La primera declaración no actualiza nada, pero incrementa la versión de la fila y arrojará una excepción de simultaneidad si la versión de la fila se cambió en el medio.
El [System.ComponentModel.DataAnnotations.Schema.Timestamp]
atributo son las anotaciones de datos equivalentes a IsRowVersion()
:
[Timestamp]
public byte[] RowVersion { get; set; }