Как сравнить временную метку SQL в .NET?

Я отобразил сущности Entity. Каждая таблица в SQL Server 2008 содержит столбец Timestamp, который отображается как массив байтов. Длина массива всегда равна 8.

Теперь мне нужно сравнить значения timestamp в .NET. Я пришел с двумя решениями, но не знаю, какой из них лучше?

  • Сравните его как массивы. Когда первая пара байтов отличается, возвращает false.
  • Преобразование массива байтов в long, сравнение longs.

Какое решение лучше? Или есть ли другое решение?

Ответ 1

Мы делаем это, сравнивая их как массивы байтов. Прекрасно работает для нас.

Ответ 2

Тип данных временной метки MS SQL Server семантически эквивалентен двоичному (8) (если не является нулевым) или varbinary (8) (если значение NULL). Ergo, сравните их как массивы байтов.

Не говоря уже о том, что накладные расходы связаны с долгой переработкой. Вы можете написать какой-то небезопасный код, чтобы получить адрес массивов байтов, отбросить их до длинных указателей и разыскать их в longs, НО для этого безопасно означает закрепление их в памяти и плот уродливого кода, чтобы сделать что-то существенно простое (и, возможно, не быстрее, чем с помощью BitConverter).

Самый быстрый способ сделать это, если производительность действительно такая критическая, самым быстрым способом было бы выполнить сравнение, используя стандартную функцию библиотеки memcmp() библиотеки C через 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 ) ;
        }

    }

}