2011-01-12 5 views
11

私はエンティティフレームワークエンティティをマップしました。 SQL Server 2008の各テーブルには、バイト配列としてマップされたタイムスタンプ列が含まれています。配列の長さは常に8です。.NETでSQLタイムスタンプを比較するには?

これで.NETのタイムスタンプ値を比較する必要があります。私は2つのソリューションを提供していますが、どれが良いか分かりません。

  • 配列と比較してください。最初のバイトのペアが異なる場合、falseを返します。
  • バイト配列をlongに変換し、longsを比較します。

どのソリューションが優れていますか?それとも他の解決策がありますか?

答えて

11

バイト配列として比較します。私たちのためにうまく動作します。

9

MS SQL Serverのタイムスタンプデータ型は、意味的にバイナリ(8)(null不可能な場合)またはvarbinary(8)(null可能な場合)と同等です。 Ergo、それらをバイトの配列として比較します。

変換に伴うオーバーヘッドが長いことは言うまでもありません。あなたは、バイト配列のアドレスを取得し、それらをlongポインタにキャストし、longにデリファレンスするための安全でないコードを書くことができます。しかし、安全に行うためには、それらをメモリに固定し、醜いコードをBitConverterを使用するよりも速くはありません)。パフォーマンスは本当に重要な場合

最速の方法は、それを行うには、最速の方法は、P /呼び出しを経由して、標準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) ; 
     } 

    } 

} 
+0

@Nicholas非常にクール –

+0

販売している学校のCプログラマを嫌うB ^) –

+0

@Nicholas +1とてもいいですが、安全でないコードを避けたいと思います。 –

関連する問題