преобразованный измененный гид - PullRequest
0 голосов
/ 09 февраля 2012

У меня есть следующий код t-sql, который я преобразовал в c #.

DECLARE @guidRegular UNIQUEIDENTIFIER, @dtmNow DATETIME  

 SELECT @guidRegular = '{5bf8e554-8dbc-4008-9d48-5c6e0a4d28d7}'  

 SELECT @dtmNow = '2012-02-09 18:31:38' 


print (CAST(CAST(@guidRegular  AS BINARY(10))  +  CAST(@dtmNow AS BINARY(6))  AS UNIQUEIDENTIFIER)) 

Когда я выполняю версию кода .net (с использованием того же Guid и DateTime), я получаю другое руководство?Похоже, это как-то связано с элементом datetime, может кто-нибудь помочь?

c # код расширения:

using system.data.linq;
...
...

   public static class GuidExtensions
    {
        public static Guid ToNewModifiedGuid(this Guid guid)
        {
            var dateTime = new DateTime(2012,02,09,18,31,38);
            var guidBinary = new Binary(guid.ToByteArray().Take(10).ToArray());
            var dateBinary = new Binary(BitConverter.GetBytes(dateTime.ToBinary()).ToArray().Take(6).ToArray());

            var bytes = new byte[guidBinary.Length + dateBinary.Length];
            Buffer.BlockCopy(guidBinary.ToArray(), 0, bytes, 0, guidBinary.ToArray().Length);
            Buffer.BlockCopy(dateBinary.ToArray(), 0, bytes, guidBinary.ToArray().Length, dateBinary.ToArray().Length);

            return new Guid(bytes);
        }
    }

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Я не удивлен, что SQL и .net будут иметь разные двоичные представления даты / времени. Я был бы удивлен, если бы они имели.

Ваш код на c # просит структуру DateTime сериализовать значение в 64-битный (8-байтовый) байтовый массив, который можно использовать для воссоздания того же значения. Затем вы выбрасываете 2 байта (год? Миллисекунда? Контрольная сумма? Кто знает?)

Ваш sql-код запрашивает движок sql взять свое внутреннее представление даты-времени (которое также составляет 8 байт), отбросить два и дать результат.

Итак:

  1. Если вы хотите идентичные значения, вам нужно прекратить полагаться на внутреннюю информацию о том, как дата / время хранятся / сериализуются. Преобразуйте его в 6 байтов, используя повторяемый метод, который вы можете записать как в .net, так и в tsql
  2. Поймите, что вы удаляете 6 байтов направляющей, которые представляют пространственно уникальную часть, и заменяете их временем. Таким образом, вы создаете GUID, в котором время закодировано дважды, и значительно увеличивает вероятность создания дубликатов GUID.

Конечно, это игнорирует более вопиющую проблему "зачем кому-то это делать?" Я собираюсь предположить, что это действительно блестящая подсистема, а не более вероятное объяснение того, что кто-то отчаянно пытается решить не ту проблему.

0 голосов
/ 21 февраля 2012

Оригинальная статья имеет недостаток в логике.Автор описывает как натуральные, так и суррогатные ключи, но не признает, что RFC для UUID можно использовать для создания натурального ключа.Конечно, для этого потребуется создать пользовательскую функцию для генерации UUID на основе некоторой информации домена решения, а не полагаться на машинную / временную функцию по умолчанию для их генерации.

Выполнение одной функции для заменыгенерация ключей имеет гораздо больший смысл, чем эта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...