我知道RowVersion
列的值本身并不是有用的,除了它每次更新行时都会更改.但是,我想知道它们是否对相对(不平等)比较有用.
如果我有一个包含RowVersion
列的表,则满足以下条件之一:
RowVersion
列中具有相同的值?谢谢.
我正在研究MVC3应用程序.我的客户端ViewModel包含一个SQL Server RowVersion属性,它是一个byte [].它在客户端呈现为Object数组.当我尝试将我的视图模型发布到控制器时,RowVersion属性始终为null.
我假设Controller序列化程序(JsonValueProviderFactory)忽略了Object数组属性.
我看过这个博客,但这不适用,因为我发布的是JSON而不是表单标记:http: //thedatafarm.com/blog/data-access/round-tripping-a-timestamp-field-with-ef4 -1-代码先和-MVC-3 /
我的视图呈现我的viewmodel:
<script type="text/javascript">
var viewModel = @Html.Raw( Json.Encode( this.Model ) );
</script>
Run Code Online (Sandbox Code Playgroud)
然后我将viewModel发布到控制器,如下所示:
var data = {
'contact': viewModel
};
$.ajax({
type: 'POST',
url: '/Contact/Save',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
dataType: 'json',
success: function (data) {
// Success
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.responseText);
}
});
Run Code Online (Sandbox Code Playgroud)
这是我在控制器中的动作:
[HttpPost]
public JsonResult Save(Contact contact) {
return this.Json( this._contactService.Save( contact ) );
}
Run Code Online (Sandbox Code Playgroud)
更新:基于达林的答案.
我希望有一个更清晰的解决方案,但由于Darin提供了唯一的答案,我将不得不添加一个自定义属性,将我的byte []"row_version"属性序列化为Base64字符串.当Base64字符串设置为新的自定义属性时,它会将字符串转换回byte [].下面是我添加到模型中的自定义"RowVersion"属性:
public byte[] …
Run Code Online (Sandbox Code Playgroud) 我遇到过一个案例,其中与LINQ to SQL相当不错的东西似乎对Entity Framework来说非常迟钝(或者可能是不可能的).具体来说,我有一个包含rowversion
属性的实体(用于版本控制和并发控制).就像是:
public class Foo
{
[Key]
[MaxLength(50)]
public string FooId { get; set; }
[Timestamp]
[ConcurrencyCheck]
public byte[] Version { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我希望能够将实体作为输入,并找到最近更新的所有其他实体.就像是:
Foo lastFoo = GetSomeFoo();
var recent = MyContext.Foos.Where(f => f.Version > lastFoo.Version);
Run Code Online (Sandbox Code Playgroud)
现在,在数据库中,这将起作用:两个rowversion
值可以相互比较而没有任何问题.在使用LINQ to SQL之前我做了类似的事情,它映射了rowversion
to System.Data.Linq.Binary
,可以进行比较.(至少在表达式树可以映射回数据库的程度上.)
但在Code First中,属性的类型必须是byte[]
.并且两个数组无法与常规比较运算符进行比较.有没有其他方法来编写LINQ to Entities将理解的数组的比较?或者将数组强制转换为其他类型,以便比较可以通过编译器?
我们正在通过链接的服务器连接在两个SQL Server数据库之间,在单独的服务器(SQL Server 2008 Enterprise 64位SP2 - 10.0.4000.0)中对一种Sync Framework进行故障排除,并且我们达到了排序的程度卡住了.
识别哪些是"待同步"的记录的逻辑当然基于ROWVERSION
值,包括使用MIN_ACTIVE_ROWVERSION()
以避免脏读.
所有SELECT
操作都封装在每个"源"端的SP中.这是一个SP的示意图:
PROCEDURE LoaderRetrieve(@LastStamp bigint, @Rows int)
BEGIN
...
(vars handling)
...
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
Select TOP (@Rows) Field1, Field2, Field3
FROM Table
WHERE [RowVersion] > @LastStampAsRowVersionDataType
AND [RowVersion] < @MinActiveVersion
Order by [RowVersion]
END
Run Code Online (Sandbox Code Playgroud)
该方法工作正常,我们通常以预期的600k /小时速率同步记录(每30秒一次作业,批量大小= 5k),但在某些时候,同步过程找不到任何单个记录要传输,即使有数千条记录的ROWVERSION
值大于@LastStamp
参数.
在检查原因时,我们发现搜索MIN_ACTIVE_ROWVERSION()
的值小于(或稍微大一些,只有5或10个增量)@LastStamp
.这当然应该不是问题,因为MIN_ACTIVE_ROWVERSION()
引入该方法是为了避免脏读和后验问题,但是:
在上述情况发生期间,我们在某些情况下看到的问题是,MIN_ACTIVE_ROWVERSION()
在很长(很长)的时间段内,例如30/40分钟,有时超过一小时,价值不会发生变化.而这个值远远低于该@@DBTS
值.
我们首先认为这与尚未提交的待处理数据库事务有关.根据MSDN关于MIN_ACTIVE_ROWVERSION()
(链接)的定义:
返回当前数据库中最低的活动rowversion值.如果在尚未提交的事务中使用rowversion值,则该rowversion值处于活动状态. …
Oracle是否具有与SQL ServerRowVersion
类似的数据类型?
插入或更新行时,相应的"版本"列(类型RowVersion
)会自动更新.
是一种在数据库中公开自动生成的唯一二进制数的数据类型.rowversion通常用作版本标记表行的机制.存储大小为8个字节.rowversion数据类型只是一个递增的数字,不保留日期或时间.
每个数据库都有一个计数器,该计数器针对在数据库中包含rowversion列的表上执行的每个插入或更新操作递增.此计数器是数据库rowversion.这会跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间.一个表只能有一个rowversion列.每次修改或插入具有rowversion列的行时,都会在rowversion列中插入递增的数据库rowversion值.
您可以使用行的rowversion列轻松确定自上次读取行以来该行中的任何值是否已更改.如果对该行进行了任何更改,则会更新rowversion值.如果没有对该行进行任何更改,则rowversion值与先前读取的值相同.
您可以向表中添加rowversion列,以便在多个用户同时更新行时帮助维护数据库的完整性.您可能还想知道在不重新查询表的情况下更新了多少行和哪些行.
我们正在使用oracle设计数据模型,并希望使用Version列来管理并发.
我还想知道Oracle世界中是否有更好的方法.
我在.NET中得到的结果如下:
var lastRowVersion = SqlHelper.ExecuteScalar(connStr, CommandType.Text, "select
top 1 rowversion from dbo.sdb_x_orginfo order by rowversion desc");
Run Code Online (Sandbox Code Playgroud)
结果是一个字节数组[0]= 0,[1]=0,[2]=0,[3]=0,[4]=0,[5]=0,[6]=30,[7]=138
,但SQL Server中的结果是0x0000000000001E8A
.
如何"0x0000000000001E8A"
在.NET中获得价值?
rowversion(时间戳)数据类型的正确类型是什么?
我知道它是8个字节,但我找不到MSDN中的链接,它告诉它是有符号还是无符号长.
我应该使用哪些代码,甚至重要吗?
byte[] SqlTimeStamp;
long longConversion;
longConversion = BitConverter.ToInt64(SqlTimeStamp,0);
TimeStamp = BitConverter.GetBytes(longConversion);
ulong ulongConversion;
ulongConversion = BitConverter.ToUInt64(SqlTimeStamp,0);
TimeStamp = BitConverter.GetBytes(ulongConversion);
Run Code Online (Sandbox Code Playgroud) 我应该如何rowversion
使用Entity Framework 比较字段?我有一个表有一个rowversion
列,我想从表中获取行版本高于指定值的数据.
byte[] rowversion = ... some value;
_context.Set<T>().Where(item => item.RowVersion > rowVersion);
Run Code Online (Sandbox Code Playgroud)
这行不起作用,它抛出错误:
不能应用于'byte []'和'byte []'类型的操作数
知道如何比较rowversion
c#/ EF中的字段吗?
是rowversion
不是在Microsoft SQL Server 2008 R2的有效的数据类型?
我正在尝试向rowversion
表中添加一列:
但是,当我尝试离开"数据类型"列时,SQL Server Management Studio会抱怨
数据类型无效.
并坚持我选择不同的数据类型:
rowversion
当rowversion
不是有效数据类型时,如何创建列?
rowversion(Transact-SQL)
timestamp是rowversion数据类型的同义词,受数据类型同义词行为的影响.在DDL语句中,尽可能使用rowversion而不是timestamp.有关更多信息,请参阅数据类型同义词(Transact-SQL).
该时间戳语法已被弃用.将在Microsoft SQL Server的未来版本中删除此功能.避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序.
额外奖金Chatter
我在 PostgreSQL 中使用 Entity Framework 6。我有一个实体,我想在其中防止并发问题,按照本文档,我添加了一个带有 [Timestamp] 属性的 RowVersion 属性,但是在保存对实体的更改后,列 RowVersion 值在数据库中保持不变。
[Timestamp]
public byte[] RowVersion { get; set; }
Run Code Online (Sandbox Code Playgroud)
我是不是遗漏了什么,还是有其他方法可以在 PostgreSQL 中处理它?
postgresql entity-framework rowversion optimistic-concurrency
rowversion ×10
sql-server ×5
c# ×3
timestamp ×3
sql ×2
asp.net-mvc ×1
byte ×1
c#-4.0 ×1
comparison ×1
inequality ×1
oracle ×1
postgresql ×1
razor ×1
transactions ×1