StrictId.EFCore 1.0.2

Suggested Alternatives

StrictId.EFCore 1.1.0

Additional Details

This version of the package allows for implicit downcasts, which can result in loss of type information and type-unsafe comparisons. Upgrade to 1.1.0 or later for better type safety.

There is a newer version of this package available.
See the version list below for details.
dotnet add package StrictId.EFCore --version 1.0.2                
NuGet\Install-Package StrictId.EFCore -Version 1.0.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StrictId.EFCore" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add StrictId.EFCore --version 1.0.2                
#r "nuget: StrictId.EFCore, 1.0.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install StrictId.EFCore as a Cake Addin
#addin nuget:?package=StrictId.EFCore&version=1.0.2

// Install StrictId.EFCore as a Cake Tool
#tool nuget:?package=StrictId.EFCore&version=1.0.2                

StrictId

Strongly-typed, ergonomic, compatible, fun to use identifiers for your entities

Get on NuGet:
StrictId EFCore HotChocolate


What

public class Person {
    public Id<Person> Id { get; init; } // Strongly typed ID, with Ulid as the underlying type
    public Id<Dog> BestFriendId { get; set; } // No confusion about what ID we are looking for here
    public List<Id> Friends { get; set; } // Non-strict/non-generic version also included
}
  • Strongly-typed IDs for your entities, or anything else
  • Ulid as the underlying value, which can easily be converted to and from Guid, string, or byte arrays
  • Ergonomic, developer-friendly usage without ceremony, boilerplate, or annoyance
  • Built-in JSON conversion support for System.Text.Json
  • Full support for Entity Framework Core incl. value converters and value generators, with StrictId.EFCore
  • Full support for HotChocolate GraphQL incl. custom scalars for Id<T> and Id, with StrictId.HotChocolate
  • Tiny memory footprint and highly efficient

How

Recommended, but optional
In your global usings file, add the following to save yourself a few keystrokes:

global using StrictId;

Create

Id<Person>.NewId(); // Generate a new random ID
new Id<Person>("01HV9AF3QA4T121HCZ873M0BKK"); // Create from ULID string
new Id<Person>("018ED2A7-8EEA-2682-20C5-9F41C7402E73"); // Create from GUID string
new Id<Person>(Ulid.NewUlid()); // Create from ULID
new Id<Person>(Guid.NewGuid()); // Create from GUID
new Id<Person>(Id.NewId()); // Create from non-typed ID

Id<Person> id = Ulid.NewUlid(); // Convert implicitly from Ulid
Id<Person> id = Guid.NewGuid(); // Convert implicitly from Guid
var id = (Id<Person>)"01HV9AF3QA4T121HCZ873M0BKK"; // Cast from string
var id = (Id<Person>)Id.NewId(); // Cast from non-typed ID

Convert

var id = new Id<Person>("01HV9AF3QA4T121HCZ873M0BKK");

id.ToString(); // "01HV9AF3QA4T121HCZ873M0BKK"
id.ToUlid(); // Same as Ulid.Parse("01HV9AF3QA4T121HCZ873M0BKK");
id.ToGuid(); // Same as Guid.Parse("018ED2A7-8EEA-2682-20C5-9F41C7402E73");
id.ToByteArray(); // byte[]
id.IdValue // Id("018ED2A7-8EEA-2682-20C5-9F41C7402E73")

With Entity Framework Core

Install StrictId.EFCore via NuGet

In your DbContext:

using StrictId.EFCore;

public class MyDatabase (DbContextOptions<MyDatabase> options) : DbContext(options)
{
    protected override void ConfigureConventions (ModelConfigurationBuilder builder)
    {
        // ...
        
        builder.ConfigureStrictId();
    }
}

To generate values:

using StrictId.EFCore;

// ...

builder.Property(e => e.Id)
    .ValueGeneratedOnAdd()
    .HasStrictIdValueGenerator();

With Hot Chocolate GraphQL

Install StrictId.HotChocolate via NuGet

On the request executor builder, configure strict IDs:

builder.Services.AddGraphQLServer()
    // ...
    .AddStrictId();

Scalars will be created for each strict ID, named {Type}Id. For example, Id<Person> would become PersonId in the GraphQL schema.

Why

  • Using Guid or Ulid as the type for IDs can easily lead to mixing up method arguments and assignments
  • Other similar packages are cumbersome, non-compatible, and frankly annoying
  • Ulid as the underlying type provides neat benefits over simple Guids, as they are ordered, making databases less fragmented, and look nicer as strings

Acknowledgements

  • Ulid - Library for ULID in C#, used for much of the underlying functionality
  • StronglyTypedId - For doing this first, but in a much more convoluted, non-ergonomic, less compatible way

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 4,501 6/6/2024
1.0.4 180 4/16/2024 1.0.4 is deprecated.
1.0.3 147 4/14/2024 1.0.3 is deprecated.
1.0.2 128 4/12/2024 1.0.2 is deprecated.
1.0.1 264 4/12/2024 1.0.1 is deprecated.