Fre*_*dou 11 c# sql-server rowversion
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)
jnm*_*nm2 19
这非常重要.您希望您的比较与SQL Server的比较具有相同的结果.SQL Server对二进制类型使用无符号比较:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
Run Code Online (Sandbox Code Playgroud)
如果您执行与long签名相同的操作,则0xFFFFFFFFFFFFFFFF表示-1.这意味着你的比较是不正确的; 它与SQL Server中完成的相同比较不匹配.
你绝对需要的是用ulong哪里0xFFFFFFFFFFFFFFFF是ulong.MaxValue.
此外,正如马克指出的那样,BitConverter.GetUInt64没有正确转换.Mark 并不是完全正确的 - BitConverter要么是大端还是小端,取决于它运行的系统.你可以自己看看.此外,即使BitConverter始终是little-endian,Array.Reverse使用堆分配和逐字节复制的性能也会降低.BitConverter从语义上或实际上来说,这只是工作的正确工具.
这就是你想要的:
static ulong BigEndianToUInt64(byte[] bigEndianBinary)
{
return ((ulong)bigEndianBinary[0] << 56) |
((ulong)bigEndianBinary[1] << 48) |
((ulong)bigEndianBinary[2] << 40) |
((ulong)bigEndianBinary[3] << 32) |
((ulong)bigEndianBinary[4] << 24) |
((ulong)bigEndianBinary[5] << 16) |
((ulong)bigEndianBinary[6] << 8) |
bigEndianBinary[7];
}
Run Code Online (Sandbox Code Playgroud)
这是我使用的解决方案:Timestamp.cs.
基本上一旦你施展Timestamp,你就不会出错.
小智 9
如果由于endian而在x86系列CPU上运行,则两者都不能正常用于比较时间戳/行反转值.时间戳的第一个字节是最重要的,但对于小端整数类型则不是这样.
在调用BitConverter.ToUInt64(ts)之前调用Array.Reverse(ts),在调用BitConverter.GetBytes(tsUInt64)之后调用另一个方向
简短回答:没关系,但我会选择UInt64.
细节:在语义上它等同于binary(8)严格来说,它既不是UInt64也不Int64是一块字节(并且以这种方式应该被管理).那说我选择UInt64因为它是一个递增的数字来保持行版本然后(从逻辑的角度来看)0xFFFFFFFFFFFFFFFF应该大于0并且它不是真的Int64(因为64位设置为1给出-1并且它小于0).
编辑:请注意,由于仅在内部SQL Server设计人员圈子中已知的原因,ROWVERSION是大端(虽然 - 显然 - bigint不是)然后您首先需要反转字节,请参阅此答案以获得良好的实现.
| 归档时间: |
|
| 查看次数: |
9033 次 |
| 最近记录: |