.NET有两种GUID数据类型:Guid,以“自然”方式命令GUID,以及SqlGuid,它将最后一个破折号后的六个字节视为最重要的.这种差异在这里详细解释:MSDN: Comparing GUID and uniqueidentifier Values.
但是,在这两种情况下,应该保持以下内容(假设所有… s相等):
57d0affe-... < 57d0afff-... < 57d0b000-...
如果是这种情况,为什么我会得到以下输出(请参阅注释)?
using System;
using System.Data.SqlTypes;
class Program
{
static void Main(string[] args)
{
var g1 = new SqlGuid("57d0affe-9d9d-11e4-bec2-e840f2ad1632");
var g2 = new SqlGuid("57d0afff-9d9d-11e4-bec2-e840f2ad1632");
var g3 = new SqlGuid("57d0b000-9d9d-11e4-bec2-e840f2ad1632");
Console.WriteLine(g1 < g2); // prints True
Console.WriteLine(g2 < g3); // prints False <- ?
Console.ReadLine();
}
}
据我所知,g2< g3也应该产生True.我是否误解了某些内容,或者这是框架中的一些错误?使用普通Guid而不是SqlGuid时,输出为True,如预期的那样.
解决方法:
比较有点复杂.
首先,有一些订单定义:
private static readonly int[] x_rgiGuidOrder = new int[16]
{10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};
然后有这种方法
private static EComparison Compare(SqlGuid x, SqlGuid y) {
//Swap to the correct order to be compared
for (int i = 0; i < SizeOfGuid; i++) {
byte b1, b2;
b1 = x.m_value [x_rgiGuidOrder[i]];
b2 = y.m_value [x_rgiGuidOrder[i]];
if (b1 != b2)
return(b1 < b2) ? EComparison.LT : EComparison.GT;
}
return EComparison.EQ;
}
然而,这不是整个故事,究竟是什么原因是来自字符串的构造函数:
public SqlGuid(String s) {
m_value = (new Guid(s)).ToByteArray();
}
它创建一个新的GUID,然后使用它的字节表示.
这给了我们以下字节值:
g2 : 255 175 208 87 157 157 228 17 190 194 232 64 242 173 22 50
g3 : 0 176 208 87 157 157 228 17 190 194 232 64 242 173 22 50
在那里我们可以看到255大于0而不是相反.
你可以找到完整的源码here
小提琴如何获得字节表示是here