以下代码可以在 NHibernate.Id.GuidCombGenerator 类中找到。该算法基于将“随机”guid 与 DateTime 组合来创建顺序(梳状)guid。我有几个与下面用 *1) 和 *2) 标记的行相关的问题:
private Guid GenerateComb()
{
byte[] guidArray = Guid.NewGuid().ToByteArray();
// *1)
DateTime baseDate = new DateTime(1900, 1, 1);
DateTime now = DateTime.Now;
// Get the days and milliseconds which will be used to build the byte string
TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
TimeSpan msecs = now.TimeOfDay;
// *2)
// Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray = BitConverter.GetBytes((long) (msecs.TotalMilliseconds / 3.333333));
// Reverse the bytes to match SQL Servers ordering
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
// Copy the bytes into the guid
Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
return new Guid(guidArray);
}
首先,对于*1),将更近的日期作为baseDate 不是更好,例如2000-01-01,以便为将来的更多值腾出空间吗?
关于 *2),当我们只对日期时间的字节感兴趣并且从不打算将值存储在 SQL Server 日期时间字段中时,为什么我们要关心 SQL Server 中日期时间的准确性?使用 DateTime.Now 提供的所有准确性不是更好吗?