Skip to content

v6.2.0

Choose a tag to compare

@github-actions github-actions released this 23 Jul 08:48
· 17 commits to master since this release

v6.2.0 — measured, diagnosed, generated

This release is the performance-and-tooling round: published benchmarks that drove two engine
optimizations to the raw-driver floor, compile-time model diagnostics, and source-generated
entity accessors
— both shipped inside the core package, no extra installs.

Published benchmarks — and the loop they exist for

The repository now carries a comparative suite (benchmarks/) against EF Core, Dapper and raw
Npgsql
over a real PostgreSQL 17: point read, filtered set, projection, paging, single insert,
100-row commit, set-based update. Results, methodology and the honest reading live in the docs:
Operations → Benchmarks.

The first run named two losses — and both were fixed at the engine level and re-measured:

Scenario First run Now The fix
Projection (500 rows) 1.29× of raw 0.92× reader-direct projectors (no entity shells, no per-query JIT) + a structural projector cache
Single insert + commit 1.84× 1.00× one-statement flushes skip the local transaction (a single statement is atomic on its own)

Where the table stands (Apple M4 Pro, .NET 10, ShortRun): every read scenario at or below the raw
Npgsql baseline within noise, ahead of EF Core across the board; the batch flush at hand-written
DbBatch speed — ~2× faster than EF Core, ~10× faster than per-row Dapper inserts.

Compile-time model diagnostics (EQD001–EQD011)

eQuantic.Core.Data now ships a Roslyn analyzer (bundled — every consumer gets it): the modeling
misuses that are wrong on every provider surface as warnings while typing, with the fix in the
message — a concurrency token no store can version, ambiguous [PartitionKey]/[ClusteringKey]
orders, multiple [EntityKey] members, invalid [Facet]s, contradictory [Unmapped], and more.
Provider-relative rules deliberately stay at runtime, where the provider is known and the message
can be exact. The full table.

Source-generated entity accessors

A source generator (also bundled) emits reflection-free accessors — construction, member reads and
writes as direct code — for every entity in the consuming compilation, registered automatically.
Relational materialization and column reads use them when present; reflection remains the
fallback contract
, so nothing changes for assemblies compiled without the generator, and types
the generated code could not honor faithfully (init-only setters, no accessible parameterless
constructor) stay on the reflection path by design.

Measured effect on the benchmarks: within noise — stated plainly in the docs, because that is the
honest finding. The accessors exist to remove the reflection dependence itself: the groundwork for
trimming/NativeAOT support.

Also in this release

  • Mapped reads (GetMappedAsync, paged maps) narrow their SELECT and build results in one pass.
  • The benchmark harness documents its methodology (per-stack idiomatic setup, state isolation) and
    reproduces with one command — Docker included, container owned by the run.

Verification

Suites green across the round on real stores: PostgreSQL 53 (through the generated accessors),
SQL Server 13, MySQL 16, MongoDB 131, Cosmos DB 41, Cassandra 94, core 62, analyzers 13.

Compatibility: no breaking changes. Requires eQuantic.Core.DataModel 4.0.0 /
eQuantic.Core.Domain 4.0.0 (as since v6.0.0).