I have two records in my student table with a row-version field. I am creating the object of that record as student class in my C# code.
My question are:
One way to find the latest rowversion is to use the StructuralComparer
var r1 = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00};
var r2 = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xFF};
bool r1_is_newer = StructuralComparisons.StructuralComparer.Compare(r1, r2) > 0;
A benefit of the structural comparisons is that they automatically deal with NULL
s
Regarding use of the BitConverter
. If the above byte arrays were converted to UInt64
using the BitConverter
, you'd end up with very high numbers and the comparison is meaningless (as the rowversion changes by one, the uint64 converted number changes by around 2^56)
If you'd like to sprinkle some LINQ over it to make it extra slow, you can use
bool r1_is_newer =
Enumerable.Zip(r1, r2, (b1, b2) => new { b1, b2 })
.SkipWhile(item => item.b1 == item.b2)
.Take(1).Any(item => item.b1 > item.b2);
rowversion
is binary(8)
, and will be returned as a byte[]
if you use SqlCommand
/SqlDataReader
. If you use EF 4.1, the corresponding property will also be byte[]
.
You could use BitConverter to convert to UInt64
and then compare. You could also return the rowversion cast as bigint
from SQL Server, which would appear as a long
in C#. In either case, the larger value would have been created later.
In my own tests, I've seen that rowversion starts at a small, positive value (not 0). If you do cast to bigint
, you'll have to consider what will happen when it reaches 2^64
. In my case, it's not something I have to worry about. If you think that will happen in your database, then you'll have to add logic to handle that in your comparison, or just stick with BitConverter.ToUInt64
.
Also, be careful if your rowversion
column accepts NULL
; You'll have to account for that if it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With