Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Simultaneidade otimista:IsConcurrencyToken e RowVersion


Tanto no EF6 quanto no EF-core, ao trabalhar com Sql Server, você deve usar este mapeamento:
modelBuilder.Entity<Product>() 
.Property(t => t.RowVersion) 
.IsRowVersion(); // Not: IsConcurrencyToken

IsConcurrencyToken configura uma propriedade como token de simultaneidade, mas (ao usá-la para um byte[] propriedade)
  • o tipo de dados é varbinary(max)
  • seu valor é sempre null se você não inicializar
  • seu valor não é incrementado automaticamente quando um registro é atualizado.

IsRowVersion por outro lado,
  • tem o tipo de dados rowversion (no Sql Server, ou timestamp em versões anteriores), então
  • seu valor nunca é nulo e
  • seu valor é sempre incrementado automaticamente quando um registro é atualizado.
  • e configura automaticamente a propriedade para ser um token de simultaneidade otimista.

Agora, quando você atualiza um Car você verá duas instruções de atualização:
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 ...

A primeira instrução não atualiza nada, mas incrementa a versão de linha e lançará uma exceção de simultaneidade se a versão de linha tiver sido alterada no meio.

O [System.ComponentModel.DataAnnotations.Schema.Timestamp] atributo é o equivalente das anotações de dados de IsRowVersion() :
[Timestamp]
public byte[] RowVersion { get; set; }