【问题标题】:How to compare SQL timestamp in .NET?如何比较 .NET 中的 SQL 时间戳?
【发布时间】:2011-01-12 17:57:58
【问题描述】:

我已经映射了实体框架实体。 SQL Server 2008 中的每个表都包含映射为字节数组的时间戳列。数组的长度始终为 8。

现在我需要比较 .NET 中的时间戳值。我提供了两种解决方案,但我不知道哪个更好?

  • 将其作为数组进行比较。当第一对字节不同时返回 false。
  • 将字节数组转换为长整数,比较长整数。

哪种解决方案更好?还是有其他解决办法?

【问题讨论】:

    标签: c# .net sql-server


    【解决方案1】:

    我们通过将它们作为字节数组进行比较来做到这一点。对我们来说很好。

    【讨论】:

      【解决方案2】:

      MS SQL Server 的时间戳数据类型在语义上等同于 binary(8)(如果不可为空)或 varbinary(8)(如果可以为空)。因此,将它们作为字节数组进行比较。

      更不用说转换为 long 会产生开销。您可以编写一些不安全的代码来获取字节数组的地址,将它们转换为长指针并将它们解引用为长指针,但是要安全地做到这一点,就意味着将它们固定在内存中以及大量丑陋的代码来做一些本质上简单的事情(并且可能不比使用 BitConverter 快)。

      如果性能真的那么关键,最快的方法是使用标准 C 库的 memcmp() 函数通过 P/Invoke 进行比较:

      using System;
      using System.Runtime.InteropServices;
      
      namespace TestDrive
      {
          class Program
          {
              static void Main()
              {
                  byte[] a = { 1,2,3,4,5,6,7,8} ;
                  byte[] b = { 1,2,3,4,5,0,7,8} ;
                  byte[] c = { 1,2,3,4,5,6,7,8} ;
                  bool isMatch ;
      
                  isMatch = TimestampCompare( a , b ) ; // returns false
                  isMatch = TimestampCompare( a , c ) ; // returns true
      
                  return ;
              }
      
              [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
              static extern int memcmp(byte[] x , byte[] y , UIntPtr count ) ;
      
              static unsafe bool TimestampCompare( byte[] x , byte[] y )
              {
                  const int LEN = 8 ;
                  UIntPtr   cnt = new UIntPtr( (uint) LEN ) ;
      
                  // check for reference equality
                  if ( x == y ) return true ;
      
                  if ( x == null || x.Length != LEN || y == null || y.Length != LEN )
                  {
                      throw new ArgumentException() ;
                  }
      
                  return ( memcmp(  x ,  y , cnt ) == 0 ? true : false ) ;
              }
      
          }
      
      }
      

      【讨论】:

      • 开玩笑的卖学 C 程序员 B^)
      • @Nicholas +1 这很好,但我想避免不安全的代码。
      • 不应该 x == yObject.ReferenceEquals(x, y),只是为了确保没有任何运算符重载关于类型
      • 除非你有一个秘密的方法来对密封类 System.Byte 或特殊类 System.Array 进行子类型化。
      • 除非你不重新发明轮子,而是使用标准的数据转换方式——BitConverter.ToInt64(binary.ToArray(), 0),是的,它是单行的。
      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2016-09-16
      • 1970-01-01
      • 2011-12-28
      • 2019-07-30
      • 2012-05-16
      • 2012-09-15
      相关资源
      最近更新 更多