2013-12-03 2 views
5

У меня есть первая модель EF Code с полем байтового массива, отмеченным атрибутом Timestamp. Мне нужно сравнить две метки времени друг с другом и определить, что является более новым. Это кажется простым, но я не уверен, какая ценность SQL Server заполняет этот массив байтов. Я просто конвертирую их в значения UInt64, например:Сравнение значений временной метки EF

BitConverter.ToInt64(item1.Timestamp, 0) < BitConverter.ToInt64(item2.TimeStamp, 0) 

... или я хожу в какую-то утонченную ловушку здесь?

+2

Почему вы используете байтовый массив вместо DateTime? – Stijn

+1

Так как работает TimeStampAttribute. «Тип версии строки (также известный как порядковый номер) - это двоичное число, которое гарантировано будет уникальным в базе данных, оно не представляет собой фактическое время. Данные версии строки не являются визуально значимыми». (http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.timestampattribute(v=vs.110).aspx) – Bas

ответ

8

Да, вы идете в ловушку. Байт-массив хранит строку rowversion в формате большого конца. Тем не менее, BitConverter.ToInt64 ожидает небольшой формат endian для архитектуры процессора x86 и x64. Я проверил простой тест с использованием BitConverter и получил начальную строку с преобразованием 0xd207000000000000 и следующую rowversion 0xd307000000000000. SQL Server увеличивает последний байт последовательности из 8 байтов, но BitConverter считает, что первый байт является самым значительным. Это не займет много времени, прежде чем ваши сравнения заказов перестанут работать время от времени.

Решение отменить порядок rowversion байт, как это:

BitConverter.ToInt64(item1.Timestamp.Reverse().ToArray(), 0) < 
BitConverter.ToInt64(item2.TimeStamp.Reverse().ToArray(), 0) 
+1

Если вам нужен ваш код для переносимости на большие компьютерные машины, вы можете сделать обратные вызовы «Reverse» условными, чтобы они были опущены, если «BitConverter.IsLittleEndian» является ложным. –

2

Rowversion - правильный тип SQL-сервера. EF использует ByteArray для сопоставления с этим. Или лучше сказал. Атрибут [Timestamp] или свободный API Property(x).IsRowVersion сопоставляется с SQL rowversion через байтовый массив.

Таким образом, если вам не нужны фактические дата и время, то ROWVERSION является рекомендуемым MS. Sql Server Rowversion

Да Значения являются признаком относительного времени в том смысле, что меньшее значение было инициировано ранее. Но если вы используете грязные чтения, вам нужно рассмотреть последствия большего, чем сравнение.

Поскольку это 8 байт, вы не будете там, когда это закончится ;-)
Так кроме грязного чтения, вы можете сравнить их да.

Похожие темы: What if rowversion rolls over

Смежные вопросы