我有一个EF Code First模型,其字节数组字段标有Timestamp属性。我需要将两个时间戳相互比较,并确定哪个更新。这似乎很简单,但我不确定SQL Server填充该字节数组的价值是什么。我只是将它们转换为UInt64值,如下所示:
BitConverter.ToInt64(item1.Timestamp, 0) < BitConverter.ToInt64(item2.TimeStamp, 0)
......或者我在这里走进一些微妙的陷阱?
答案 0 :(得分:12)
是的,你正走进一个陷阱。字节数组以big endian格式存储rowversion。但是,BitConverter.ToInt64
期望在x86和x64 CPU架构上使用小端格式。我使用BitConverter进行了一个简单的测试,得到的初始rowversion为0xd207000000000000,下一个rowversion为0xd307000000000000。 SQL Server正在递增8字节序列的最后一个字节,但BitConverter认为第一个字节是最重要的。在您的订单比较暂时停止工作之前,它不会需要很多增量。
解决方案是颠倒rowversion字节的顺序,如下所示:
BitConverter.ToInt64(item1.Timestamp.Reverse().ToArray(), 0) <
BitConverter.ToInt64(item2.TimeStamp.Reverse().ToArray(), 0)
答案 1 :(得分:3)
Rowversion是SQL Server中的正确类型。 EF使用ByteArray映射到那个。
或者更好地说。属性[Timestamp]
或流畅的API Property(x).IsRowVersion
通过字节数组映射到SQL rowversion。
因此,除非您需要实际的日期和时间,否则ROWVERSION是MS推荐的方法。 Sql Server Rowversion
是这些值表示相对时间,因为较小的值是先前启动的。 但是如果你使用脏读,你需要考虑大于比较的含义。
因为它是8个字节,所以当它耗尽时你不会在那里;-)
除了脏读之外,您可以将它们进行比较。