我刚刚阅读了一篇关于NHibernate从系统时间(Guid.Comb)创建GUID的能力的博客文章,从而避免了大量的数据库碎片.您可以将其称为客户端等效于SQL Server顺序ID.
有没有办法在Linq-to-Sql项目中使用类似的策略(通过在代码中生成Guid)?
C#(安全)代码(NHibernate Guid Comb Generator的赞美)
Guid GenerateComb() { byte[] destinationArray = Guid.NewGuid().ToByteArray(); DateTime time = new DateTime(0x76c, 1, 1); DateTime now = DateTime.Now; TimeSpan span = new TimeSpan(now.Ticks - time.Ticks); TimeSpan timeOfDay = now.TimeOfDay; byte[] bytes = BitConverter.GetBytes(span.Days); byte[] array = BitConverter.GetBytes((long) (timeOfDay.TotalMilliseconds / 3.333333)); Array.Reverse(bytes); Array.Reverse(array); Array.Copy(bytes, bytes.Length - 2, destinationArray, destinationArray.Length - 6, 2); Array.Copy(array, array.Length - 4, destinationArray, destinationArray.Length - 4, 4); return new Guid(destinationArray); }
github上的源代码链接:https: //github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Id/GuidCombGenerator.cs
COMB按以下方式生成:
DECLARE @aGuid UNIQUEIDENTIFIER SET @aGuid = CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)
转录为C#的内容如下所示:
public static unsafe Guid CombGuid() { Guid guid = Guid.NewGuid(); byte[] bytes = guid.ToByteArray(); long ticks = DateTime.Now.Ticks; fixed( byte* pByte = bytes ) { int* pFirst = (int *)(pByte + 10); short* pNext = (short*)(pByte + 14); *pFirst = (int)(ticks & 0xFFFFFF00); *pNext = (short)ticks; } return new Guid( bytes ); }