问题描述
我正在创建我应用程序中使用的默认并发策略。
我决定采取乐观的策略。
我的所有实体都被映射为 Table type(TPT)
(使用继承)。我很快就了解到,在Entity Framework中使用RowVersion类型的继承性列出现问题:
Product
ID INT IDENTITY PRIMARY KEY
RowVersion ROWVERSION
Car(继承产品记录)
颜色TYNIINT NOT NULL,
AnotherProperty ....
如果我更新了 Car的记录
从 Product
表中的RowVersion列表将不会更新。
我打算使用一个类型为<$ 产品
中的c $ c> datetime2(7),如果修改了继承此表的表的任何记录,则手动更新。 >
我想我正在重塑轮子。
有另一种方式使用乐观并发策略与 ROWVERSION
在实体框架中使用表类型(TPT)
修改
我的映射:
class Product
{
int Id {get;组; }
string Name {get;组; }
byte [] RowVersion {get;组; }
}
class Car:Product
{
int Color {get;组;
}
CodeFirst 约定。 b
$ b
只有产品
实体上的RowVersion属性具有自定义定义:
modelBuilder.Entity< Product>()
.Property(t => t.RowVersion)
.IsConcurrencyToken();
你必须使用映射
modelBuilder.Entity< Product>()
.Property(t => t.RowVersion)
.IsRowVersion(); // Not:IsConcurrencyToken
IsConcurrencyToken 将属性配置为并发令牌,但是(当用于 byte []
属性时)
- 数据类型是nvarchar(max)
- 如果不初始化它,它的值始终为null
- 当它的记录是更新。
- 有数据类型
rowversion
(在Sql Server中,或timestamp
在早期版本中),所以 - 其值永远不为空,并且
- 当更新记录时,其值始终自动递增。 / li>
- ,它会自动将属性配置为乐观的con货币令牌
现在,当您更新 Car
时,您会看到两个更新语句:
DECLARE @p int
更新[dbo]
SET @p = 0
WHERE(([Id] = @ 0)AND([Rowversion] = @ 1))
SELECT [Rowversion]
FROM [dbo] [产品]
WHERE @@ ROWCOUNT> 0 AND [Id] = @ 0
更新[dbo]。[Car]
SET ...
第一个语句不会更新任何东西,但它会增加rowversion,如果rowversion在其间进行更改,它将引发并发异常。
顺便说一下, IsRowVersion
相当于 [Timestamp]
属性:
[Timestamp]
public byte [] RowVersion {get;组; }
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();
You have to use the 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 nvarchar(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, ortimestamp
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 changed in-between.
By the way, IsRowVersion
is equivalent to the [Timestamp]
attribute:
[Timestamp]
public byte[] RowVersion { get; set; }
这篇关于乐观并发:IsConcurrencyToken和RowVersion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!