次のコードは、NHibernate.Id.GuidCombGeneratorクラスにあります。アルゴリズムは、「ランダム」GUIDとDateTimeの組み合わせに基づいて、シーケンシャル(comb)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の日時フィールドに値を格納するつもりがないのに、なぜSQLServerのDateTimeの精度を気にするのでしょうか。DateTime.Nowから入手できるすべての精度を使用する方が良いのではないでしょうか。