ZeroAlloc.ValueObjects.EfCore
2.2.4
See the version list below for details.
dotnet add package ZeroAlloc.ValueObjects.EfCore --version 2.2.4
NuGet\Install-Package ZeroAlloc.ValueObjects.EfCore -Version 2.2.4
<PackageReference Include="ZeroAlloc.ValueObjects.EfCore" Version="2.2.4" />
<PackageVersion Include="ZeroAlloc.ValueObjects.EfCore" Version="2.2.4" />
<PackageReference Include="ZeroAlloc.ValueObjects.EfCore" />
paket add ZeroAlloc.ValueObjects.EfCore --version 2.2.4
#r "nuget: ZeroAlloc.ValueObjects.EfCore, 2.2.4"
#:package ZeroAlloc.ValueObjects.EfCore@2.2.4
#addin nuget:?package=ZeroAlloc.ValueObjects.EfCore&version=2.2.4
#tool nuget:?package=ZeroAlloc.ValueObjects.EfCore&version=2.2.4
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 144 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 444× faster than CSharpFunctionalExtensions. On a single-intvalue object it runs at parity with Vogen. - 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, 144 B | 444× |
GetHashCode, two-field Money |
0 B | CSharpFunctionalExtensions, 72 B on the first call per instance, then cached | — |
Equals, single-int value object |
0 B | Vogen, 0 B | both below resolution |
.NET 10.0.13, CSharpFunctionalExtensions 3.7.0, Vogen 8.0.7, measured 2026-10-21. record and record struct allocate 0 B and run in the same time as ZeroAlloc.ValueObjects on two-field Equals. The performance page has every row, including GetHashCode, where record is faster, 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.21)
- ZeroAlloc.ValueObjects (>= 2.2.4)
-
net9.0
- Microsoft.EntityFrameworkCore (>= 9.0.21)
- ZeroAlloc.ValueObjects (>= 2.2.4)
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.5 | 0 | 10/21/2026 |
| 2.2.4 | 0 | 10/21/2026 |
| 2.2.3 | 0 | 10/21/2026 |
| 2.2.2 | 1,332 | 10/16/2026 |
| 2.2.1 | 391 | 10/15/2026 |
| 2.2.0 | 555 | 10/12/2026 |
| 2.1.1 | 996 | 10/11/2026 |
| 2.1.0 | 798 | 10/10/2026 |
| 2.0.12 | 1,299 | 9/30/2026 |
| 2.0.11 | 857 | 9/28/2026 |
| 2.0.10 | 1,289 | 9/26/2026 |
| 2.0.9 | 1,140 | 9/21/2026 |
| 2.0.8 | 260 | 9/20/2026 |
| 2.0.7 | 218 | 9/20/2026 |
| 2.0.6 | 873 | 9/19/2026 |
| 2.0.5 | 429 | 8/10/2026 |
| 2.0.4 | 131 | 8/9/2026 |
| 2.0.3 | 118 | 8/8/2026 |
| 2.0.2 | 113 | 8/7/2026 |
| 2.0.0 | 124 | 8/7/2026 |