Generate a UUID (GUID) in C#

How to generate a UUID in C#: Guid.NewGuid for v4, Guid.CreateVersion7 on .NET 9 for time ordered ids, the N, D, B and P format strings, TryParse, and the SQL Server sort order trap.

Try it here

Generate a UUID to paste into your C# code, in any version and format.

Format

Your UUIDs

Copy one, copy them all, or download the list. The format options above apply to everything shown here.

    The standard way: Guid.NewGuid

    Guid id = Guid.NewGuid();      // version 4, random
    string s = id.ToString();      // "f47ac10b-58cc-4372-a567-0e02b2c3d479"

    In .NET a UUID is called a Guid. It is the same 128 bit value in the same RFC layout. NewGuid uses the operating system's secure random source and produces a v4.

    Time ordered v7 on .NET 9

    Guid id = Guid.CreateVersion7();                      // now
    Guid id = Guid.CreateVersion7(DateTimeOffset.UtcNow); // explicit timestamp
    
    id.Version;   // 7, also new in .NET 9

    On .NET 8 and earlier use the UUIDNext package: UuidToolkit.CreateUuidV7(). Use v7 for entity keys so inserts stay sequential, with one important exception covered below.

    Format strings

    id.ToString("D");   // f47ac10b-58cc-4372-a567-0e02b2c3d479   default, hyphens
    id.ToString("N");   // f47ac10b58cc4372a5670e02b2c3d479       32 hex, no hyphens
    id.ToString("B");   // {f47ac10b-58cc-4372-a567-0e02b2c3d479} braces
    id.ToString("P");   // (f47ac10b-58cc-4372-a567-0e02b2c3d479) parentheses
    id.ToString("D").ToUpperInvariant();                  // uppercase, the Windows habit

    Parse and validate

    if (Guid.TryParse(input, out Guid parsed))
    {
        // valid, any of the D, N, B, P forms accepted, either case
    }
    
    Guid.TryParseExact(input, "D", out parsed);   // only the hyphenated form
    Guid.Empty;                                    // 00000000-0000-0000-0000-000000000000, the nil UUID

    The SQL Server trap

    SQL Server's uniqueidentifier does not sort by the first bytes. It compares the last six bytes first, then works leftwards in groups. A v7 GUID, whose timestamp is in the first bytes, is therefore not sequential to SQL Server and a clustered index on it still fragments. Options:

    • Use NEWSEQUENTIALID() as the column default and let SQL Server generate ids.
    • Generate ids in .NET in SQL Server's byte order. UUIDNext has Database.SqlServer for exactly this.
    • Use v7 as the key but make the clustered index something else.

    On PostgreSQL and MySQL, v7 sorts as expected and none of this applies.

    Entity Framework Core

    public class Order
    {
        public Guid Id { get; set; } = Guid.CreateVersion7();
    }
    
    // or let EF generate on add
    modelBuilder.Entity<Order>().Property(o => o.Id).ValueGeneratedOnAdd();

    Mistakes to avoid

    • new Guid() is not a new id. It is Guid.Empty, all zeros. Use Guid.NewGuid().
    • Guid.ToByteArray() is not RFC byte order. The first three groups are little endian. Use ToByteArray(bigEndian: true) on .NET 9+ when talking to other systems.
    • Mixing cases in string comparisons. Compare Guid values, not strings.

    Frequently asked questions

    Is a GUID the same as a UUID?

    Yes. GUID is the Microsoft name. The value, layout and versions are identical to RFC UUIDs, and Guid.NewGuid() produces a standard v4.

    How do I generate a UUID v7 in C#?

    Guid.CreateVersion7() on .NET 9 or newer. On older versions install UUIDNext and call UuidToolkit.CreateUuidV7().

    Why does my sequential GUID still fragment the SQL Server index?

    Because SQL Server sorts uniqueidentifier by its last bytes. Use NEWSEQUENTIALID or a generator that writes the timestamp where SQL Server sorts, such as UUIDNext's SQL Server mode.

    ↑ Top
    Copied!