在 EF6 和 EF-core 中,使用 SQL Server 时,必须使用此映射:
modelBuilder.Entity<Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not: IsConcurrencyToken
IsConcurrencyToken确实将属性配置为并发令牌,但是(当将其用于byte[]
财产)
- 数据类型是
varbinary(max)
- 它的价值总是
null
如果你不初始化它
- 当记录更新时,它的值不会自动递增。
是行版本 https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.configuration.binarypropertyconfiguration.isrowversion%28v=vs.113%29.aspx另一方面,
- 有数据类型
rowversion
(在 SQL Server 中,或timestamp
在早期版本中),所以
- 它的值永远不会为空,并且
- 当记录更新时,它的值总是自动递增。
- 它会自动将该属性配置为乐观并发令牌。
现在,当您更新Car
你会看到两个更新语句:
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 ...
第一个语句不会更新任何内容,但它会增加 rowversion,如果 rowversion 在中间发生更改,它将引发并发异常。
The [System.ComponentModel.DataAnnotations.Schema.Timestamp]
属性是相当于的数据注释IsRowVersion()
:
[Timestamp]
public byte[] RowVersion { get; set; }
请注意,官方文档 https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application是不正确的。它说IsConcurrencyToken
是流利等价的[Timestamp]
属性。然而,IsRowVersion
是等价的。