如何比较。net中的SQL时间戳?

时间:2022-04-03 13:36:55

I have mapped Entity framework entities. Each table in SQL Server 2008 contains Timestamp column which is mapped as byte array. The length of array is always 8.

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

Now I need to compare timestamp values in .NET. I come with two solutions but I don't know which one is better?

现在我需要比较。net中的时间戳值。我有两个解决方案,但我不知道哪个更好?

  • Compare it as arrays. When first pair of bytes is different return false.
  • 作为数组进行比较。当第一对字节不同时返回false。
  • Convert byte array to long, compare longs.
  • 将字节数组转换为long,比较longs。

Which solution is better? Or is there any other solution?

哪种解决方案更好?或者还有其他的解决办法吗?

2 个解决方案

#1


11  

We do it by comparing them as byte arrays. Works fine for us.

我们将它们作为字节数组进行比较。对我们来说没问题。

#2


9  

MS SQL Server's timestamp data type is semantically equivalent to binary(8) (if non-nullable) or varbinary(8) (if nullable). Ergo, compare them as arrays of bytes.

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

Not to mention there's overhead involved in converting to long. You could write some unsafe code to get the address of the byte arrays, cast those to long pointers and dereference them into longs, BUT to do that safely means pinning them in memory and a raft of ugly code to do something essentially simple (and probably no faster than using BitConverter).

更不用说转换到long的开销了。你可以写一些不安全代码字节数组的地址,把那些长指针和废弃多头,但这样做安全意味着把他们记忆和一系列丑陋的代码基本上做一些简单(可能没有比使用BitConverter)。

The fastest way to do it, if performance is really that critical, the fastest way would be to do the comparison using the standard C library's memcmp() function via P/Invoke:

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

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 ) ;
        }

    }

}

#1


11  

We do it by comparing them as byte arrays. Works fine for us.

我们将它们作为字节数组进行比较。对我们来说没问题。

#2


9  

MS SQL Server's timestamp data type is semantically equivalent to binary(8) (if non-nullable) or varbinary(8) (if nullable). Ergo, compare them as arrays of bytes.

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

Not to mention there's overhead involved in converting to long. You could write some unsafe code to get the address of the byte arrays, cast those to long pointers and dereference them into longs, BUT to do that safely means pinning them in memory and a raft of ugly code to do something essentially simple (and probably no faster than using BitConverter).

更不用说转换到long的开销了。你可以写一些不安全代码字节数组的地址,把那些长指针和废弃多头,但这样做安全意味着把他们记忆和一系列丑陋的代码基本上做一些简单(可能没有比使用BitConverter)。

The fastest way to do it, if performance is really that critical, the fastest way would be to do the comparison using the standard C library's memcmp() function via P/Invoke:

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

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 ) ;
        }

    }

}