Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace SomeNameSpace
- {
- class CombGuid
- {
- /*
- * "COMB" Guids are a little better then standard .Net GUID's
- * for use as primary keys. The are generated in sequence,
- * which is better for indexing and scanning. This is similar to
- * the NewSequentialID() functionality in SQL 2005+, but Comb Guid's
- * can be generated outside of the SQL database and passed in as
- * a parameter, so you know in code what your primary key
- * is without having to pull it from the database after insert.
- */
- #region CombGuid Explaination
- //http://www.ideablade.com/techtip_improve_your_guid.htm
- /*********************************
- *
- /// <summary>Create a new Guid.Comb.</summary>
- /// <remarks>
- /// Version by jtmueller, Jul 9, 2002.
- /// <![CDATA[
- /// http://www.informit.com/discussion/index.asp?postid=a8275a70-0698-46f0-8c8f-bf687464628c&rl=1
- /// ]]>
- /// The author wonders:
- /// "One issue is that while the resolution for a DATETIME in SQL Server is 1/300th of a second,
- /// the resolution for a DateTime in .NET is 1/10000th of a second (100 nanoseconds).
- /// This means that the sequential part of the COMB will change more frequently
- /// than in the SQL Server version, but I'm not sure if this is a good or a bad thing."
- /// On the chance that this is a problem, we've gone with the version below.
- /// </remarks>
- public static Guid NewComb() {
- byte[] dateBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
- byte[] guidBytes = Guid.NewGuid().ToByteArray();
- // copy the last six bytes from the date to the last six bytes of the GUID
- Array.Copy(dateBytes, dateBytes.Length - 7, guidBytes, guidBytes.Length - 7, 6);
- return new Guid(guidBytes);
- }
- *
- *********************************/
- #endregion
- /// <summary>Create a new Guid.Comb.</summary>
- /// <remarks>
- /// Version by glapointe, Aug 16, 2002
- /// <![CDATA[
- /// http://www.informit.com/discussion/index.asp?postid=a8275a70-0698-46f0-8c8f-bf687464628c&rl=1
- /// ]]>
- /// This one purports to "match exactly (or pretty darn close) the combs created in SQL Server."
- /// However, I modified slightly to use UtcNow and static BaseDate values.
- /// UtcNow gives cross-timezone ordering of records inserted with Guid.Comb keys.
- /// </remarks>
- public static Guid NewComb() {
- byte[] guidArray = System.Guid.NewGuid().ToByteArray();
- DateTime now = DateTime.UtcNow; // was: DateTime now = DateTime.Now;
- // Get the days and milliseconds which will be used to build the byte string
- TimeSpan days = new TimeSpan(now.Ticks - msBaseDateTicks);
- TimeSpan msecs = new TimeSpan(now.Ticks - (new DateTime(now.Year, now.Month, now.Day).Ticks));
- // Convert days and msecs to byte arrays
- // SQL Server is accurate to 1/300th of a millisecond
- // .NET DateTime ticks are in milliseconds
- // so we divide .NET ticks 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 System.Guid(guidArray);
- }
- /// <summary>Extract datetime part of a Guid.Comb.</summary>
- /// <remarks>
- /// Please note: Because I modified <see cref="NewComb"/> to use Utc datetime,
- /// this function returns the date in Universal Time;
- /// you may want to convert back to local time with
- /// <code>GetDateFromComb(aGuidComb).ToLocalTime();</code>
- /// </remarks>
- public static DateTime GetDateFromComb(System.Guid guid) {
- byte[] daysArray = new byte[4];
- byte[] msecsArray = new byte[4];
- byte[] guidArray = guid.ToByteArray();
- // Copy the date parts of the guid to the respective byte arrays.
- Array.Copy(guidArray, guidArray.Length - 6, daysArray, 2, 2);
- Array.Copy(guidArray, guidArray.Length - 4, msecsArray, 0, 4);
- // Reverse the arrays to put them into the appropriate order
- Array.Reverse(daysArray);
- Array.Reverse(msecsArray);
- // Convert the bytes to ints
- int days = BitConverter.ToInt32(daysArray, 0);
- int msecs = BitConverter.ToInt32(msecsArray, 0);
- DateTime date = msBaseDate.AddDays(days);
- date = date.AddMilliseconds(msecs * 3.333333);
- return date;
- }
- private static DateTime msBaseDate = new DateTime(1900, 1, 1);
- private static long msBaseDateTicks = msBaseDate.Ticks;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement