ZeroAlloc.ValueObjects.EfCore
2.2.2
dotnet add package ZeroAlloc.ValueObjects.EfCore --version 2.2.2
NuGet\Install-Package ZeroAlloc.ValueObjects.EfCore -Version 2.2.2
<PackageReference Include="ZeroAlloc.ValueObjects.EfCore" Version="2.2.2" />
<PackageVersion Include="ZeroAlloc.ValueObjects.EfCore" Version="2.2.2" />
<PackageReference Include="ZeroAlloc.ValueObjects.EfCore" />
paket add ZeroAlloc.ValueObjects.EfCore --version 2.2.2
#r "nuget: ZeroAlloc.ValueObjects.EfCore, 2.2.2"
#:package ZeroAlloc.ValueObjects.EfCore@2.2.2
#addin nuget:?package=ZeroAlloc.ValueObjects.EfCore&version=2.2.2
#tool nuget:?package=ZeroAlloc.ValueObjects.EfCore&version=2.2.2
ZeroAlloc.ValueObjects
Source-generated value objects and strongly-typed IDs for .NET: record-speed equality on the classes and structs you already have, with no allocation and no base class, NativeAOT-ready.
Why ZeroAlloc.ValueObjects
- Equality allocates nothing.
Equals,GetHashCode,==and!=allocate 0 B on a class and on a struct, asserted by tests. CSharpFunctionalExtensions'ValueObjectallocates 96 B perEqualsin the same benchmark. - As fast as
record, without rewriting your types to records. Equality on a two-field value object runs in the same time asrecordand 14.6× faster than CSharpFunctionalExtensions. Equality on a single-intvalue object is 13× faster than Vogen's. - Works under NativeAOT and trimming. No reflection in generated code, including the EF Core converter registration. A NativeAOT smoke app is published and run in CI.
- Mistakes fail the build. An ID strategy that does not fit its backing type, such as Snowflake on a
Guid, is compile error ZATI001.
Install
dotnet add package ZeroAlloc.ValueObjects
Quick start
using ZeroAlloc.ValueObjects;
var price = new Money(10m, "EUR");
var prices = new HashSet<Money> { price, new Money(10m, "EUR") };
Console.WriteLine(price == new Money(10m, "EUR")); // True: compared by value, 0 B
Console.WriteLine(prices.Count); // 1: safe as a set or dictionary key
OrderId id = OrderId.New(); // sortable ULID
Console.WriteLine($"{id} {OrderId.Parse(id.ToString()) == id}");
[ValueObject]
public partial class Money
{
public decimal Amount { get; }
public string Currency { get; }
public Money(decimal amount, string currency) => (Amount, Currency) = (amount, currency);
}
[TypedId(Strategy = IdStrategy.Ulid)]
public readonly partial record struct OrderId;
Money keeps its constructor, its base class and its shape. The generator adds the equality members and a ToString, without the with, Deconstruct and EqualityContract a record brings.
What you get
- Value objects on existing types:
[ValueObject]on anypartial classorpartial struct, including classes that inherit from a non-record base. - Member control: opt members in with
[EqualityMember]or out with[IgnoreEqualityMember]. Nullable reference properties compare null-safely. - Strongly-typed IDs:
[TypedId]with ULID, UUIDv7, Snowflake and Sequential strategies, plus an assembly-wide default. - JSON through a generated
System.Text.Jsonconverter that reads and writes with 0 B allocated, asserted by tests. - ASP.NET Core binding: IDs implement
IParsable<T>andISpanParsable<T>, so(OrderId id) => …route parameters just work. - EF Core: ZeroAlloc.ValueObjects.EfCore maps every typed ID in an assembly with one generated, trim-safe call.
- Snowflake worker IDs from a number, an environment variable or a factory. ZeroAlloc.ValueObjects.Hosting adds a factory that resolves services.
- Serialisation: ZeroAlloc.Serialisation writes single-value objects as their underlying value in JSON, MessagePack and MemoryPack.
Performance
BenchmarkDotNet. Allocations are exact. The time column is the alternative's time divided by ZeroAlloc.ValueObjects', from the same run.
| Operation | ZeroAlloc.ValueObjects | Alternative | Alternative's time |
|---|---|---|---|
Equals, two-field Money |
0 B | CSharpFunctionalExtensions, 96 B | 14.6× |
GetHashCode, two-field Money |
0 B | CSharpFunctionalExtensions, 88 B | 16.1× |
Equals, single-int value object |
0 B | Vogen, 0 B | 13× |
record and record struct allocate 0 B and run in the same time as ZeroAlloc.ValueObjects on the two-field rows. The performance page has every row, including GetHashCode, where Vogen ties, and the typed-ID benchmarks cover generation and parsing per strategy.
Learn more
- Documentation: valueobjects.zeroalloc.net. Good starting points: why not just use
record, typed IDs, the production checklist for IDs and the diagnostics reference for value objects and typed IDs. - Moving from CSharpFunctionalExtensions or hand-written equality: migration guide. Release history: CHANGELOG.md.
- Related packages: ZeroAlloc.Mapping, ZeroAlloc.Results, ZeroAlloc.Serialisation.
- Issues and pull requests are welcome on GitHub.
- MIT licensed. See LICENSE.
| Product | Versions 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. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.EntityFrameworkCore (>= 9.0.20)
- ZeroAlloc.ValueObjects (>= 2.2.2)
-
net9.0
- Microsoft.EntityFrameworkCore (>= 9.0.20)
- ZeroAlloc.ValueObjects (>= 2.2.2)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on ZeroAlloc.ValueObjects.EfCore:
| Package | Downloads |
|---|---|
|
ZeroAlloc.Scheduling.EfCore
EF Core job store adapter for ZeroAlloc.Scheduling. |
|
|
ZeroAlloc.Outbox.EfCore
EF Core store adapter for ZeroAlloc.Outbox. |
|
|
ZeroAlloc.Saga.EfCore
Entity Framework Core durable persistence backend for ZeroAlloc.Saga. Single shared SagaInstance table, row-version OCC, retry-on-conflict. Native AOT compatible. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.2 | 1,221 | 10/16/2026 |
| 2.2.1 | 378 | 10/15/2026 |
| 2.2.0 | 537 | 10/12/2026 |
| 2.1.1 | 995 | 10/11/2026 |
| 2.1.0 | 797 | 10/10/2026 |
| 2.0.12 | 1,298 | 9/30/2026 |
| 2.0.11 | 856 | 9/28/2026 |
| 2.0.10 | 1,285 | 9/26/2026 |
| 2.0.9 | 1,139 | 9/21/2026 |
| 2.0.8 | 259 | 9/20/2026 |
| 2.0.7 | 217 | 9/20/2026 |
| 2.0.6 | 871 | 9/19/2026 |
| 2.0.5 | 427 | 8/10/2026 |
| 2.0.4 | 129 | 8/9/2026 |
| 2.0.3 | 117 | 8/8/2026 |
| 2.0.2 | 112 | 8/7/2026 |
| 2.0.0 | 122 | 8/7/2026 |
| 1.7.2 | 239 | 8/6/2026 |
| 1.7.1 | 348 | 6/11/2026 |
| 1.7.0 | 121 | 5/18/2026 |