Zowel in EF6 als in EF-core, wanneer je met Sql Server werkt, moet je deze mapping gebruiken:
modelBuilder.Entity<Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not: IsConcurrencyToken
IsConcurrencyToken configureert een eigenschap wel als gelijktijdigheidstoken, maar (bij gebruik voor een byte[]
eigendom)
- het gegevenstype is
varbinary(max)
- de waarde is altijd
null
als je het niet initialiseert - de waarde wordt niet automatisch verhoogd wanneer een record wordt bijgewerkt.
IsRowVersion aan de andere kant,
- heeft datatype
rowversion
(in Sql Server, oftimestamp
in eerdere versies), dus - de waarde ervan is nooit null, en
- de waarde ervan wordt altijd automatisch verhoogd wanneer een record wordt bijgewerkt.
- en het configureert de eigenschap automatisch als een optimistisch gelijktijdigheidstoken.
Wanneer u nu een Car
bijwerkt je ziet twee update-statements:
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 ...
Het eerste statement werkt niets bij, maar het verhoogt de rowversion, en het zal een gelijktijdigheidsuitzondering genereren als de rowversion tussendoor werd gewijzigd.
De [System.ComponentModel.DataAnnotations.Schema.Timestamp]
attribuut is het equivalent van de gegevensannotaties van IsRowVersion()
:
[Timestamp]
public byte[] RowVersion { get; set; }