![]() |
VOOZH | about |
dotnet add package Eternet.Crud.Relational --version 3.1.37
NuGet\Install-Package Eternet.Crud.Relational -Version 3.1.37
<PackageReference Include="Eternet.Crud.Relational" Version="3.1.37" />
<PackageVersion Include="Eternet.Crud.Relational" Version="3.1.37" />Directory.Packages.props
<PackageReference Include="Eternet.Crud.Relational" />Project file
paket add Eternet.Crud.Relational --version 3.1.37
#r "nuget: Eternet.Crud.Relational, 3.1.37"
#:package Eternet.Crud.Relational@3.1.37
#addin nuget:?package=Eternet.Crud.Relational&version=3.1.37Install as a Cake Addin
#tool nuget:?package=Eternet.Crud.Relational&version=3.1.37Install as a Cake Tool
Relational CRUD runtime, generated relational bridge conventions, bulk primitives, and relational outbox support for
Eternet.Mediator.
dotnet add package Eternet.Crud.Relational
As of April 2026, the supported authoring model is:
IDomainEvent plus relational outbox projection as the default outbox modelCreateEntityCommand<Response> / UpdateEntityCommand<Response> / DeleteEntityCommand<Response> and
[HandlerForEntity<TEntity>] only as compatibility pathsThe modern relational lane is centered on a single explicit relational request type:
public sealed partial class UpdateJournalEntryHandler :
UpdateJournalEntry,
IRelationalUpdateImplementation<UpdateJournalEntryRelational.Request>
{
public override Response Handle(Request request) => request.StepsResults!.Response!;
}
public static partial class UpdateJournalEntryRelational
{
public sealed partial record Request
: RelationalUpdateEntityCommand<AccountingContext, JournalEntry, int>
{
public override int GetKey() => Id;
}
}
For update work, the internal relational request above is the supported replacement for authoring new features on
UpdateEntityCommand<Response>.
The last two weeks materially changed both Eternet.Crud.Relational and Eternet.Crud.Relational.Generator:
IRelational*Implementation<TRelationalRequest> declares one
explicit internal relational request typeStepResult<T> and preserve compatible custom relational result types for
single-entity lanesGeneratedPipelineRuntime is no longer the public runtime anchor for generated bridge glue; generated code now stays
behind assembly-local helpers backed by GeneratedBindingRuntimeIDomainEvent emission plus registered projector translation;
the old legacy outbox compatibility APIs were removed[RelationalEntityBinding("Alias")] can publish an additional downstream alias for the aggregate entity while keeping
the default Entity outputFor new relational features:
IEndpointCreate, IEndpointUpdate, IEndpointDelete, IEndpointUpsert, or the relevant query contract.IRelationalCreate/Update/Delete/UpsertImplementation<TRelationalRequest> interfaces.RelationalCreateEntityCommand<...>, RelationalUpdateEntityCommand<...>,
RelationalDeleteEntityCommand<...>, or RelationalUpsertEntityCommand<...>.Eternet.Crud.Relational.Generator augment that request, generate the bridge, and publish the reserved
downstream outputs.IDomainEvent emission in the app-owned relational business handler or
pipeline steps.The preferred bridge ownership split is:
request.StepsResultsFor new migrations, prefer a bridge-only public handler when the public side only needs response assembly. Put
write-specific derived state on the relational pipeline instead of producing it as public keyed state. Public keyed-state
binding remains supported for compatibility and for transport-layer facts that genuinely belong before the bridge.
When the internal relational request has generated pipeline steps, the generated bridge copies that request's
StepsResults object to request.StepsResults.RelationalStepsResults. Public response assembly can read auxiliary
relational-side outputs through that nested property without moving lookup/check steps back to the public pipeline.
When a generated mediator pipeline already owns custom multi-entity behavior, migrate it to
EntityChangesCommand<TDbContext, TResponse> instead of forcing a primitive companion. This keeps lookup/check/mutation
steps visible on the public pipeline, removes only the explicit SaveChanges step, and lets UnitOfWorkBehavior own the
transaction and final save. The generator analyzer marks this deterministic path with
CodeFixKind=RelationalEntityChangesPipeline only for preserved-state cases it can prove, such as ticket-action
preservation or one shared transaction. It keeps the diagnostic non-codefixable for database-generated key reads,
intermediate flushes, get-or-create flows, and bulk item derived-state flows.
For generated pipeline migrations, ECR015 is intentionally single-DbContext. If the analyzer sees pipeline evidence
for more than one DbContext, it does not offer the deterministic migration. Transaction boundary steps are identified
semantically by following local call trees to EF Core DatabaseFacade.BeginTransaction*, DatabaseFacade.CommitTransaction*,
or IDbContextTransaction.Commit* calls. When the boundary belongs to the same DbContext as the recommended relational
command, the diagnostic emits TransactionBoundarySteps, TransactionStartSteps, and TransactionCommitSteps so EAC can
remove explicit start/commit steps without relying on step names.
For homogeneous set writes, keep the same request-first model and switch the internal relational request to one of the bulk bases:
RelationalBulkCreateCommand<...>RelationalBulkDeleteCommand<...>RelationalBulkUpdateCommand<...>Bulk create consumes the relational request's GetItems() result. If each item needs a lookup-derived value such as a
vendor or tenant id, include that value in the typed item input before GetItems() materializes entities, derive it in
the relational lane, or choose EntityChangesCommand<TDbContext, TResponse> for a richer workflow.
Legacy relational surfaces still compile, but they are no longer the design target for new code:
[HandlerForEntity<TEntity>] remains compatibility-onlyCreateEntityCommand<Response>, UpdateEntityCommand<Response>, and DeleteEntityCommand<Response> remain
compatibility-onlyConfigureGeneratedRelationalCommand(...) remains deprecated migration scaffolding*RelationalHooks are already unsupportedEternet.Crud.Relational.Generator discovers the relational key path from deterministic EF metadata and explicit
relational contracts instead of naming heuristics (Id, <EntityName>Id, [Key]) or IIntIdentity/IStringIdentity;
the remaining cleanup is the runtime/public-surface identity couplingThe relational identity decoupling work is tracked in :
IIntIdentity and IStringIdentity as part of the modern relational authoring modelIIdentityThat future wave is intentionally scoped to Crud.Relational first; it does not require broad immediate cleanup across
all of Eternet.Mediator.
Eternet.Crud.Relational 3.0.0 aligned with the ScopedStates retirement in Eternet.Mediator.
GeneratedRelationalCommandBinder no longer depends on a public ScopedStates service or constructor argument.GeneratedBindingRuntime and the ambient generated runtime
scope.ScopedStates manually should migrate to
GeneratedBindingRuntime.EnterScope() and GeneratedBindingRuntime.Publish(...) when they need runtime state
in-process.Migration guide:
../../Eternet.Mediator/docs/scoped-states-breaking-change-v3.md
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.1.37 | 43 | 6/17/2026 |
| 3.1.36 | 109 | 6/14/2026 |
| 3.1.35 | 87 | 6/10/2026 |
| 3.1.34 | 94 | 6/9/2026 |
| 3.1.33 | 96 | 6/4/2026 |
| 3.1.32 | 105 | 6/4/2026 |
| 3.1.31 | 127 | 5/31/2026 |
| 3.1.30 | 109 | 5/27/2026 |
| 3.1.29 | 110 | 5/26/2026 |
| 3.1.28 | 137 | 5/21/2026 |
| 3.1.27 | 93 | 5/20/2026 |
| 3.1.26 | 94 | 5/20/2026 |
| 3.1.25 | 90 | 5/20/2026 |
| 3.1.24 | 156 | 5/19/2026 |
| 3.1.23 | 105 | 5/18/2026 |
| 3.1.22 | 159 | 5/14/2026 |
| 3.1.21 | 98 | 5/11/2026 |
| 3.1.20 | 161 | 5/8/2026 |
| 3.1.19 | 175 | 5/5/2026 |
| 3.1.18 | 107 | 5/4/2026 |
Aggregate-root lane semantics: create makes new roots; update handles root-governed child mutations.