当前位置:Gxlcms >
数据库问题 >
C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)
C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)
时间:2021-07-01 10:21:17
帮助过:3人阅读
public class GuidHelper
2 {
3 private static bool initialised;
4 private static int count;
5
6 private static long time;
7 private static long timelast;
8 private static ushort sequence;
9
10 private static byte[] address;
//网卡MAC
11 private static readonly object locker =
new object();
12 public static Guid NewSequentialId()
13 {
14 lock(locker)
15 {
16 if (!
initialised)
17 {
18 timelast =
UuidGetSystemTime();
19 count =
TICKS_PER_CLOCK_TICK;
20 Random rand =
new Random(
1);
21 sequence = (
ushort)(((rand.Next(
1,
32767) &
0xFF) <<
8) + rand.Next(
1,
32767) &
0xFF);
22 sequence &=
0x1FFF;
23 address =
GetAddressBytes();
24 initialised =
true;
25 }
26 while (
true)
27 {
28 time =
UuidGetSystemTime();
29 if (time >
timelast)
30 {
31 count =
0;
32 break;
33 }
34 if (time <
timelast)
35 {
36 sequence = (
ushort)((sequence +
1) &
0x1FFF);
37 count =
0;
38 break;
39 }
40 if (count <
TICKS_PER_CLOCK_TICK)
41 {
42 count++
;
43 break;
44 }
45 }
46
47 timelast =
time;
48 time +=
count;
49
50 byte[] guidArray =
new byte[
16];
51
52 uint data1 = (
uint)(time &
0xffffffff);
53 ushort data2 = (
ushort)((time >>
32) &
0xffff);
54 ushort data3 = (
ushort)((time >>
48) &
0x0fff);
55 /* This is a version 1 UUID */
56 data3 |= (
1 <<
12);
57
58 guidArray[
3] = (
byte)data1;
59 guidArray[
2] = (
byte)(data1 >>
8);
60 guidArray[
1] = (
byte)(data1 >>
16);
61 guidArray[
0] = (
byte)(data1 >>
24);
62 guidArray[
5] = (
byte)data2;
63 guidArray[
4] = (
byte)(data2 >>
8);
64 guidArray[
7] = (
byte)data3;
65 guidArray[
6] = (
byte)(data3 >>
8);
66 guidArray[
8] = (
byte)(sequence &
0xff);
67 guidArray[
9] = (
byte)((sequence &
0x3f00) >>
8);
68 guidArray[
9] |=
0x80;
69 Array.Copy(address,
0, guidArray,
10,
6);
70
71 return new Guid(guidArray);
72 }
//locker
73 }
//UuidCreateSequential
74
75 private static readonly int TICKS_PER_CLOCK_TICK =
1000;
76 private static readonly int SECSPERDAY =
86400;
77 private static readonly int TICKSPERSEC =
10000000;
78 private static readonly long SECS_15_OCT_1582_TO_1601 = (
17 +
30 +
31 +
365 *
18 +
5) *
SECSPERDAY;
79 private static readonly long TICKS_15_OCT_1582_TO_1601 = SECS_15_OCT_1582_TO_1601 *
TICKSPERSEC;
80 private static long UuidGetSystemTime()
81 {
82 DateTime dt =
DateTime.Now;
83 var ft =
dt.ToFileTime();
84 ft +=
TICKS_15_OCT_1582_TO_1601;
85 return ft;
86 }
87
88 private static byte[] GetAddressBytes()
89 {
90 byte[] bytes;
91 NetworkInterface[] nic =
NetworkInterface.GetAllNetworkInterfaces();
92 if (nic ==
null || nic.Length <
1)
93 {
94 bytes =
new byte[
6];
95 bytes[
0] =
0x01;
96 return bytes;
97 }
98 bytes = nic[
0].GetPhysicalAddress().GetAddressBytes();
99 return bytes;
100 }
101 }
代码写的比较粗糙,不过功能已经实现,有需要的朋友可以自行优化!
C#实现SQLSERVER数据库中有序GUID生成(NewSequentialId)
标签: