Pensei que, por especificação, os Guids do .NET v7 seriam gerados sequencialmente, o que significa:
var guid1 = Guid.CreateVersion7();
var guid2 = Guid.CreateVersion7();
var isGreater = guid2.CompareTo(guid1);
No entanto, para minha surpresa, não é esse o caso — às vezes, o segundo gerado Guid
é "maior" que o primeiro, e às vezes o contrário. É assim que eles deveriam funcionar?
De acordo com o RFC 9562 , o UUIDv7 deve ser classificado apenas pelos bytes brutos, em vez do método antigo de 32 bits, 2x 16 bits e o restante na ordem inversa.
Em C# você pode fazer isso usando
SequenceCompareTo
on a,Span
que você pode criar usandoMemoryMarshal.CreateSpan
.Você pode criar um
IComparer
para isso usandoComparer<Guid>.Create
.dotnetfiddle
Ainda não há garantia de que você obtenha IDs sequenciais, a menos que a implementação tenha os contadores opcionais . Parece que o .NET não está fazendo isso. O código-fonte (abr.) está abaixo:
Você pode ver que apenas os campos
version
evar
estão sendo preenchidos.Uma maneira de obter UUIDv7 monotônico garantido é manter seu próprio contador de data e ajustá-lo manualmente, conforme recomendado no RFC.
CreateVersion7
aceita um registro de data e hora que podemos passar. Ele usa uma conversão Unix para milissegundos, então precisamos ajustar com base nisso.Talvez você queira adicionar segurança de thread aqui.