public static class generator
{
[DllImport ("rpcrt4.dll", SetLastError = True)]
public static extern int uuidcreatesequential (out GUID GUID);
Private Const int RPC_S_OK = 0;
public static Guid Createrpcrt4guid ()
{
GUID guid;
int result = UuidCreateSequential (out GUID);
if (result = = RPC_S_OK)
return GUID;
Else
return Guid.NewGuid ();
}
public static Guid Createsecuentialguid ()
{
byte[] uid = Guid.NewGuid (). Tobytearray ();
byte[] Bindate = bitconverter.getbytes (DateTime.UtcNow.Ticks);
byte[] Secuentialguid = new Byte[uid. Length];
secuentialguid[0] = uid[0];
secuentialguid[1] = uid[1];
secuentialguid[2] = uid[2];
secuentialguid[3] = uid[3];
secuentialguid[4] = uid[4];
secuentialguid[5] = uid[5];
secuentialguid[6] = uid[6];
//Set the the 8th byte to ' 1100 '
//later we ll be Able to validate it is generated by us
SECUENTIALGUID[7] = (byte) (0xc0 | (0xf & Uid[7]));
The last 8 bytes are sequential,
It minimizes index fragmentation
To a degree as long as there are not a large
Number of Secuential-guids generated per millisecond
secuentialguid[9] = bindate[0];
secuentialguid[8] = bindate[1];
secuentialguid[15] = bindate[2];
secuentialguid[14] = bindate[3];
secuentialguid[13] = bindate[4];
secuentialguid[12] = bindate[5];
secuentialguid[11] = bindate[6];
secuentialguid[10] = bindate[7];
return new Guid (SECUENTIALGUID);
}
public static Guid Createcombguid ()
{
byte[] Guidarray = Guid.NewGuid (). Tobytearray ();
DateTime basedate = new DateTime (1900, 1, 1);
DateTime now = DateTime.Now;
Get the days and milliseconds which'll be used to build the byte string
TimeSpan days = new TimeSpan (now. Ticks-basedate.ticks);
TimeSpan msecs = Now. TimeOfDay;
Convert to a byte array
Note This SQL Server is accurate to 1/300th the 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);
}
}
Each method generates only 10 records, and the results are as follows
RPCRT4: |
Secuential: |
Comb: |
F8373adb-cf34-11e2-be8d-d43d7e333b2c F8373adc-cf34-11e2-be8d-d43d7e333b2c F8373add-cf34-11e2-be8d-d43d7e333b2c F8373ade-cf34-11e2-be8d-d43d7e333b2c F8373adf-cf34-11e2-be8d-d43d7e333b2c F8373ae0-cf34-11e2-be8d-d43d7e333b2c F8373ae1-cf34-11e2-be8d-d43d7e333b2c F8373ae2-cf34-11e2-be8d-d43d7e333b2c F8373ae3-cf34-11e2-be8d-d43d7e333b2c F8373ae4-cf34-11e2-be8d-d43d7e333b2c |
e8edcc23-9c22-c3b1-04d1-08d07e5fad6c 15c44698-4b52-c379-04d1-08d07e5fad6c a4abcb36-71e9-c2a2-04d1-08d07e5fad6c bb03c46a-ab7a-ca27-04d1-08d07e5fad6c e4b7b99e-2a8f-cb0a-04d1-08d07e5fad6c 26ac7070-3294-ca22-04d1-08d07e5fad6c 423a83c7-633a-c98c-04d1-08d07e5fad6c f2480bdb-2260-c112-04d1-08d07e5fad6c 3b76a6dc-8534-cd29-04d1-08d07e5fad6c e12fbfe7-dc1f-c57b-04d1-08d07e5fad6c |
65d8b46f-ea29-41f8-af76-a1d600e29f85 2c95c4c2-aca4-46de-b842-a1d600e29f85 C6f054ea-dbb4-432c-aed3-a1d600e29f85 2b47c23c-ac18-467c-8c2d-a1d600e29f85 4dbe1536-ccb1-4fc4-b145-a1d600e29f85 Cccd4c08-6c52-4b12-90fc-a1d600e29f85 F6f07bde-5108-43c0-9294-a1d600e29f85 921a018f-9545-447b-8c99-a1d600e29f85 Fbc560a3-acbe-48da-9b06-a1d600e29f85 Bbfbbe7f-2bc6-4bd7-bbae-a1d600e29f85 |
From the results alone, the first is more convenient to use.
The problem with this approach, however, is that sorting in SQL Server is messy, so when sorting is needed, it is necessary to simply process the build and add a little code
Byte[] Guidbytes = GUID. Tobytearray ();
Array.reverse (guidbytes, 0, 4);
Array.reverse (Guidbytes, 4, 2);
Array.reverse (Guidbytes, 6, 2);
View Code
The final code becomes:
public static GUID Createrpcrt4guid () {GUID guid;
int result = UuidCreateSequential (out GUID); if (result = = RPC_S_OK) {byte[] Guidbytes = GUID.
Tobytearray ();
Array.reverse (guidbytes, 0, 4);
Array.reverse (Guidbytes, 4, 2);
Array.reverse (Guidbytes, 6, 2);
return new Guid (guidbytes);
else return Guid.NewGuid (); }