【问题标题】:Comparing EF timestamp values比较 EF 时间戳值
【发布时间】:2013-12-03 09:22:48
【问题描述】:

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

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

...还是我在这里走进了一些微妙的陷阱?

【问题讨论】:

  • 为什么使用字节数组而不是日期时间?
  • 因为 TimeStampAttribute 就是这样工作的。 “行版本类型(也称为序列号)是保证在数据库中唯一的二进制数。它不代表实际时间。行版本数据在视觉上没有意义。” (msdn.microsoft.com/en-us/library/…)

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


【解决方案1】:

是的,你正在走进一个陷阱。字节数组以大端格式存储行版本。但是,BitConverter.ToInt64 期望在 x86 和 x64 CPU 架构上使用小端格式。我使用 BitConverter 运行了一个简单的测试,得到了 0xd207000000000000 的初始行版本和 0xd307000000000000 的下一个行版本。 SQL Server 正在递增 8 字节序列的最后一个字节,但 BitConverter 认为第一个字节是最重要的。在您的订单比较偶尔停止工作之前不会花费太多增量。

解决办法是颠倒rowversion字节的顺序,像这样:

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

【讨论】:

  • 如果您需要将代码移植到大端机器上,您可以有条件地调用Reverse,以便在BitConverter.IsLittleEndian 为假时将其省略。
【解决方案2】:

Rowversion 是 SQL Server 中的正确类型。 EF 使用 ByteArray 来映射到它。 或者更好的说法。属性 [Timestamp] 或 fluent API Property(x).IsRowVersion 通过字节数组映射到 SQL 行版本。

因此,除非您需要实际的日期和时间,否则 ROWVERSION 是 MS 推荐的方法。 Sql Server Rowversion

是的 这些值是相对时间的指示,从某种意义上说,较小的值是先启动的。 但是,如果您使用脏读,则需要考虑大于比较的含义。

因为它是 8 个字节,所以当它用完时你不会在那里;-)
所以除了脏读之外,你可以比较它们。

相关话题:What if rowversion rolls over

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 2014-12-12
    • 1970-01-01
    • 2016-07-26
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    相关资源
    最近更新 更多