比较EF时间戳值

时间:2013-12-03 09:22:48

标签: c# sql-server entity-framework ef-code-first

我有一个EF Code First模型,其字节数组字段标有Timestamp属性。我需要将两个时间戳相互比较,并确定哪个更新。这似乎很简单,但我不确定SQL Server填充该字节数组的价值是什么。我只是将它们转换为UInt64值,如下所示:

BitConverter.ToInt64(item1.Timestamp, 0) < BitConverter.ToInt64(item2.TimeStamp, 0)

......或者我在这里走进一些微妙的陷阱?

2 个答案:

答案 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个字节,所以当它耗尽时你不会在那里;-)
除了脏读之外,您可以将它们进行比较。

相关主题:What if rowversion rolls over