Som observeret af Alberto Ferrari
og diskuteret her på StackOverflow
, Microsoft SQL Server sorterer GUID'er ved at sammenligne bytes i en bestemt rækkefølge. Som MySQL vil sortere en BINARY(16)
"straight-forward", alt hvad vi skal gøre, er at omorganisere bytes, når du læser/skriver til databasen.
NHibernate giver os mulighed for at definere brugerdefinerede datatyper, som kan bruges i kortlægninger mellem database og objekter. Jeg har implementeret en BinaryGuidType
, der er i stand til at omarrangere bytes produceret af Guid.ToByteArray()
i henhold til den måde, hvorpå MSSQL sorterer GUID'er og omorganiserer dem tilbage til det format, der accepteres af Guid(byte[])
konstruktør.
Byterækkefølgen ser sådan ud:
int[] ByteOrder = new[] { 10,11,12,13,14,15,8,9,6,7,4,5,0,1,2,3 };
Gemmer en System.Guid
til en BINARY(16)
går sådan her:
var bytes = ((Guid) value).ToByteArray();
var reorderedBytes = new byte[16];
for (var i = 0; i < 16; i++)
{
reorderedBytes[i] = bytes[ByteOrder[i]];
}
NHibernateUtil.Binary.NullSafeSet(cmd, reorderedBytes, index);
Læsning af bytes tilbage i en System.Guid
går sådan her:
var bytes = (byte[]) NHibernateUtil.Binary.NullSafeGet(rs, names[0]);
if (bytes == null || bytes.Length == 0) return null;
var reorderedBytes = new byte[16];
for (var i = 0 ; i < 16; i++)
{
reorderedBytes[ByteOrder[i]] = bytes[i];
}
Fuld kildekode til BinaryGuidType
her.
Dette ser ud til at fungere godt. Ved at skabe og vedholde 10.000 nye objekter i en tabel, gemmes de fuldstændig sekventielt uden tegn på indeksfragmentering.