2011-01-12 26 views
11

Mam zmapowany Entity framework podmiotów. Każda tabela w programie SQL Server 2008 zawiera kolumnę Znacznik czasu odwzorowany jako tablica bajtów. Długość tablicy jest zawsze 8.Jak porównać znacznik czasu SQL w .NET?

Teraz muszę porównać wartości znacznika czasu w .NET. Mam dwa rozwiązania, ale nie wiem, który z nich jest lepszy?

  • Porównaj to jako tablice. Gdy pierwsza para bajtów jest różna, zwracana jest wartość false.
  • Konwertuj tablicę bajtów na długą, porównuj długie.

Które rozwiązanie jest lepsze? Czy jest jakieś inne rozwiązanie?

Odpowiedz

11

Robimy to porównując je jako tablice bajtowe. Działa dobrze dla nas.

9

Typ danych znacznika czasu serwera MS SQL Server jest semantycznie równoważny binarnie (8) (jeśli nie można go nullować) lub varbinary (8) (jeśli jest zerowy). Ergo, porównaj je jako tablice bajtów.

Nie wspominając już o tym, że konwersja trwała długo. Mógłbyś napisać jakiś niebezpieczny kod, by uzyskać adres tablic bajtowych, rzucić je na długie wskaźniki i odciąć je w długie, ALE robienie tego bezpiecznie oznacza przypięcie ich do pamięci i mnóstwo brzydkiego kodu, aby zrobić coś zasadniczo prostego (i prawdopodobnie nie szybciej niż przy użyciu BitConvertera).

Najszybszy sposób to zrobić, jeśli wydajność jest naprawdę krytyczna, najszybszym sposobem byłoby zrobić porównanie użyciu memcmp() funkcji standardowej biblioteki C za pośrednictwem 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) ; 
     } 

    } 

} 
+0

@Nicholas bardzo fajnie –

+0

Jest sprzedawanym w szkole programistą C^^) –

+0

@Nicholas +1 jest bardzo miły, ale chciałbym uniknąć niebezpiecznego kodu. –