-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Right now you can look at https://stackoverflow.com/questions/7437970/how-to-query-code-first-entities-based-on-rowversion-timestamp-value and see how difficult this is- it's next to impossible to get right.
Since we can't have comparison operators on byte arrays, the next most idiomatic thing would be to have the following methods in SqlFunctions (or DbFunctions, if possible), naming convention following the Expression class:
bool LessThan(byte[], byte[])bool LessThanOrEqual(byte[], byte[])bool GreaterThan(byte[], byte[])bool GreaterThanOrEqual(byte[], byte[])
Questions
- I don't know if there is any value in
EqualandNotEqual. They would be useful if evaluated client-side, because they would be semantically purer than the==operator which compares byte arrays by reference. The semantics of byte array==are incorrect because SQL compares binary by value (as it should). - Could they be extension methods? Might be a nice experience, might not.
Considered alternatives
Casting
A function that would be cool for other purposes would be long SqlFunctions.Cast(byte[]), but that would not work for this scenario because SQL Server only has signed comparisons, plus it's less performant server-side:
select case when cast(0x0FFFFFFFFFFFFFFF as bigint) < cast(0xFFFFFFFFFFFFFFFF as bigint)
then 'unsigned' else 'signed - oops' endDoing a multi-step comparison would get around the signed comparison issue, but that's hacky and slower. Casting to char(8) would subject you to collation comparisons.
Idiomatic binary type
Another alternative would be to use a Binary primitive struct that wraps a byte array and provides all the value-comparison operators and has an implicit conversion to and from a byte array. Additionally, a Timestamp primitive type (mine) for rowversion columns. This puts comparison operators back on the table and would be ideal over SqlFunctions, but obviously will have to wait for #242. If it speeds up #242 all the better!