我有以下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)我得到一个不同的guid?看起来它与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);
}
}
答案 0 :(得分:2)
我并不感到惊讶,SQL和.net会有不同的日期/时间二进制表示。如果他们有,我会感到惊讶。
您的c#代码要求DateTime结构将值序列化为64位(8字节)字节数组,该数组可用于重新创建相同的值。然后你丢掉2个字节(年份?毫秒?校验和?谁知道?)
你的sql代码要求sql引擎获取日期时间的内部表示 - 也就是8个字节 - 扔掉两个,然后给出结果。
所以:
当然,这忽略了一个更明显的问题:“为什么有人想这样做?”我将假设它是一个非常出色的子系统,而不是更有可能的解释,有人正拼命试图解决错误的问题。
答案 1 :(得分:0)
原始文章的逻辑存在缺陷。作者描述了自然密钥和代理密钥,但没有认识到UUID的RFC可用于创建自然密钥。当然,这样做需要创建一个自定义函数,用于根据某些解决方案域信息生成UUID,而不是依赖于默认的基于机器/时间的函数来生成它们。
使用单个函数替换键的生成比这更有意义。