乐观并发:IsConcurrencyToken 和 RowVersion [英] Optimistic concurrency: IsConcurrencyToken and RowVersion

查看:27
本文介绍了乐观并发:IsConcurrencyToken 和 RowVersion的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建将在我的应用程序中使用的默认并发策略.

我决定采用乐观的策略.

我的所有实体都映射为 Table per Type (TPT)(使用继承).很快我就了解到,在 Entity Framework 上使用带有继承的 RowVersion 类型的列时会出现问题:

产品Id INT 身份主键行版本 ROWVERSION汽车(继承产品记录)颜色 TYNIINT 不为空,另一个属性....

如果我更新 Car 表的记录,Product 表中的 RowVersion 列将不会更新.

我打算在 Product 中使用 datetime2 (7) 类型的列,并在继承该表的表的任何记录被修改时手动更新它.>

我想我正在重新发明轮子.

在实体框架中使用 Table per Type (TPT) 时,是否有另一种方法可以将乐观并发策略与 ROWVERSION 一起使用?

编辑

我的映射:

class 产品{int ID { 获取;放;}字符串名称 { 获取;放;}字节 [] 行版本 { 获取;放;}}类别 汽车 : 产品{int 颜色 { 得到;放;}}

CodeFirst 约定.

只有 Product 实体上的 RowVersion 属性有自定义定义:

modelBuilder.Entity().Property(t => t.RowVersion).IsConcurrencyToken();

解决方案

EF6 和 EF-core 中,使用 Sql Server 时,必须使用此映射:

modelBuilder.Entity().Property(t => t.RowVersion).IsRowVersion();//不是:IsConcurrencyToken

IsConcurrencyToken 确实将属性配置为并发令牌,但是(当将其用于 byte[] 属性时)

  • 数据类型为varbinary(max)
  • 如果你不初始化它,它的值总是null
  • 当记录更新时,它的值不会自动增加.

IsRowVersion 另一方面,

  • 具有数据类型 rowversion(在 SQL Server 中,或在早期版本中为 timestamp),所以
  • 它的值永远不会为空,并且
  • 当记录更新时,它的值总是自动递增.
  • 并且它会自动将该属性配置为乐观并发令牌.

现在,当您更新 Car 时,您将看到两个更新语句:

DECLARE @p int更新 [dbo].[产品]设置@p = 0WHERE (([Id] = @0) AND ([Rowversion] = @1))选择 [行版本]来自 [dbo].[产品]哪里@@ROWCOUNT >0 AND [Id] = @0更新 [dbo].[汽车]放 ...

第一条语句没有更新任何内容,但它增加了 rowversion,如果在这之间更改了 rowversion,它将抛出并发异常.

[System.ComponentModel.DataAnnotations.Schema.Timestamp] 属性是等效于 IsRowVersion() 的数据注释:

[时间戳]公共字节[] RowVersion { 获取;放;}

I'm creating the default concurrency strategy that I will use in my application.

I decided for an optimistic strategy.

All of my entities are mapped as Table per Type (TPT) (using inheritance). I soon learned that there is a problem when using columns of type RowVersion with inheritance on Entity Framework:

Product

Id INT IDENTITY PRIMARY KEY
RowVersion ROWVERSION

Car (inherits Product records)

Color TYNIINT NOT NULL,
AnotherProperty....   

If I update a record of the Car table the RowVersion column from Product table will not be updated.

I plan to use a column of type datetime2 (7) in Product and update it manually if any records of the tables that inherit this table are modified.

I think I'm reinventing the wheel.

Is there another way to use the optimistic concurrency strategy with ROWVERSION when using Table per Type (TPT) in Entity Framework?

Edit

My mapping:

class Product
{
    int Id { get; set; }
    string Name { get; set; }
    byte[] RowVersion { get; set; }
}

class Car : Product
{
    int Color { get; set; }
}

CodeFirst conventions.

Only the RowVersion property on Product entity has custom definitions:

modelBuilder.Entity<Product>() 
    .Property(t => t.RowVersion) 
    .IsConcurrencyToken();

解决方案

Both in EF6 and EF-core, when working with Sql Server, you have to use this mapping:

modelBuilder.Entity<Product>() 
.Property(t => t.RowVersion) 
.IsRowVersion(); // Not: IsConcurrencyToken

IsConcurrencyToken does configure a property as concurrency token, but (when using it for a byte[] property)

  • the data type is varbinary(max)
  • its value is always null if you don't initialize it
  • its value is not auto-incremented when a record is updated.

IsRowVersion on the other hand,

  • has datatype rowversion (in Sql Server, or timestamp in earlier versions), so
  • its value is never null, and
  • its value is always auto-incremented when a record is updated.
  • and it automatically configures the property to be an optimistic concurrency token.

Now when you update a Car you'll see two 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 ...

The first statement doesn't update anything, but it increments the rowversion, and it will throw a concurrency exception if the rowversion was changed in-between.

The [System.ComponentModel.DataAnnotations.Schema.Timestamp] attribute is the data annotations equivalent of IsRowVersion():

[Timestamp]
public byte[] RowVersion { get; set; }

这篇关于乐观并发:IsConcurrencyToken 和 RowVersion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆