Es spielt eine Rolle. Ihr Vergleich soll dasselbe Ergebnis haben wie der Vergleich von SQL Server. SQL Server verwendet vorzeichenlose Vergleiche für binäre Typen:
select case when 0x0FFFFFFFFFFFFFFF < 0xFFFFFFFFFFFFFFFF then 'unsigned' else 'signed' end
Wenn Sie dasselbe mit long
machen die signiert ist, 0xFFFFFFFFFFFFFFFF
steht für -1
. Das bedeutet, dass Ihr Vergleich falsch sein wird; es stimmt nicht mit dem gleichen Vergleich überein, der in SQL Server durchgeführt wird.
Was Sie auf jeden Fall wollen, ist die Verwendung von ulong
wobei 0xFFFFFFFFFFFFFFFF
ist ulong.MaxValue
.
Endianness ist auch wichtig
Zusätzlich, wie Mark betonte, BitConverter.GetUInt64
konvertiert nicht richtig. Mark hat nicht ganz recht - BitConverter
ist entweder Big-Endian oder Little-Endian, je nachdem, auf welchem System es läuft. Sie können dies selbst sehen. Auch wenn BitConverter immer Little-Endian war, Array.Reverse
ist mit einer Heap-Zuordnung und byteweisem Kopieren weniger leistungsfähig. BitConverter
ist einfach weder semantisch noch praktisch das richtige Werkzeug für den Job.
Das wollen Sie:
static ulong BigEndianToUInt64(byte[] bigEndianBinary)
{
return ((ulong)bigEndianBinary[0] << 56) |
((ulong)bigEndianBinary[1] << 48) |
((ulong)bigEndianBinary[2] << 40) |
((ulong)bigEndianBinary[3] << 32) |
((ulong)bigEndianBinary[4] << 24) |
((ulong)bigEndianBinary[5] << 16) |
((ulong)bigEndianBinary[6] << 8) |
bigEndianBinary[7];
}
Die sauberste Lösung
Hier ist die Lösung, die ich verwende:Timestamp.cs.
Im Grunde sobald Sie auf Timestamp
gecastet haben , Sie können nichts falsch machen.
Beides funktioniert aufgrund von Endian nicht richtig zum Vergleichen von Zeitstempel-/Zeilenversionswerten, wenn Sie auf einer CPU der x86-Familie ausgeführt werden. Das erste Byte eines Zeitstempels ist am signifikantesten, jedoch nicht für Little-Endian-Integer-Typen.
Rufen Sie Array.Reverse(ts) auf, bevor Sie BitConverter.ToUInt64(ts) aufrufen, und für die andere Richtung nach dem Aufruf von BitConverter.GetBytes(tsUInt64)
Kurze Antwort:Es spielt keine Rolle, aber ich würde UInt64
wählen .
Details:semantisch äquivalent zu binary(8)
streng genommen ist es also weder UInt64
noch Int64
aber nur ein Stück Bytes (und auf diese Weise sollte es verwaltet werden). Das heißt, ich würde UInt64
wählen weil es eine aufsteigende Zahl ist Zeilenversion dann (aus logischer Sicht) 0xFFFFFFFFFFFFFFFF
zu halten sollte größer als 0
sein und es ist nicht wahr für Int64
(weil 64 Bit auf 1 gesetzt -1
ergeben und es ist kleiner als 0
).
Bearbeiten :Beachten Sie, dass aus Gründen, die nur im Kreis der SQL Server-Designer bekannt sind, ROWVERSION
ist Big-Endian (während - offensichtlich - bigint
ist nicht), dann müssen Sie zuerst Bytes umkehren, siehe diese Antwort für eine nette Implementierung.