Relational Semantics for Object Systems
Cohesive.Relations is the relational layer of the Cohesive Systems architecture. It unifies:
- Object-to-object mapping
- DTO hydration and denormalization
- Projections into read models and search indexes
- Predicate construction and query compilation
- Relationship-aware querying across entity graphs
- Multi-store joins
- EDI and flat-file transformation
- JSON Schema-to-JSON Schema mapping
- ML feature extraction and inference projection
Most systems treat these as separate concerns:
- AutoMapper
- LINQ and EF queries
- Elastic DSL
- ETL pipelines
- EDI mapping tools
- Reporting layers
Cohesive treats them as one semantic problem:
Relations between structured observations of state.
This is not a new idea. Engineers already speak about relational models, projections, indexing, joins, and separation of concerns. Cohesive makes these ideas first-class and composable.
- Relational Semantics for Object Systems
- Summary
- The Problems It Solves
- DTO Sprawl & Parallel Class Hierarchies
- Persistence–Domain Split
- Complex Hydration Graphs
- Ad Hoc Mapping (EDI, flat files)
- Lack of Structural Testing
- Ad Hoc Query Construction
- Manual Materialization & Dependency Tracking
- Ad Hoc Evolution Strategies
- Semantic Drift Across Environments
- What It Provides
- Canonical Shapes
- Declarative, Typed Mapping
- Mapping Coverage & Structural Validation
- Backend-Aware Query Compilation
- Decoupled Join Semantics
- Systematic Index Projections & View Materialization
- ML Feature Projections
- A Structured Intermediate Representation (IR)
- External Mapping DSL
- Incremental Adoption
- Comparison Matrix
- The Big Idea
Summary
Cohesive.Relations is a library for defining canonical data shapes and declarative relations once, then compiling them into validated mappings, queries, projections, and materializations across multiple backends.
It replaces parallel DTO hierarchies and handwritten join and projection code with a typed model that compiles to a small intermediate representation (IR). That IR enables build-time validation (type, cardinality, and required-field coverage), backend-aware query compilation (SQL, Cosmos, Elastic, in-memory, etc.), and systematic view and index materialization with explicit dependency tracking and evolution support.
Use it when the same domain semantics must reliably flow through storage, APIs, search, EDI or flat files, analytics, and ML feature pipelines without semantic drift.
The Problems It Solves
Modern systems fragment around data shape, mapping, and querying. The same semantics are represented, joined, serialized, indexed, and evolved in multiple incompatible ways.
Cohesive.Relations addresses these structural failures directly.
DTO Sprawl & Parallel Class Hierarchies
- Storage DTO
- API DTO
- Search DTO
- EDI DTO
- Export DTO
Each differs slightly. Each evolves independently. Each drifts. Even when everything is “just JSON,” semantics are duplicated.
Result: fragile systems, silent field loss, inconsistent behavior.
Persistence–Domain Split
The domain/storage split is typically triggered by:
- Field renames
- Type changes
- Field splits/merges
- Schema migration
- Backward compatibility requirements
Instead of systematizing evolution, teams fork the model.
Now you have:
- Canonical entity
- Storage DTO
- Migration logic
- Dual-read/write logic
- Divergent serialization
Result: duplicated semantics and complex evolution paths.
Complex Hydration Graphs
Reading a single entity is easy. Reading several related entities is not. This leads to:
- Handwritten joins
- EF includes or raw SQL
- Separate indexing logic
- Ad hoc in-memory correlation
- Multiple access paths for the same projection
Cosmos doesn’t support joins. Elastic behaves differently from SQL. Each backend forces different code.
Result: duplicated query logic and inconsistent projections.
Ad Hoc Mapping (EDI, flat files)
Mapping between shapes, particularly EDI, is usually:
- Imperative
- Loop- and qualifier-sensitive
- Hard to validate
- Hard to diff
- Hard to test
Most mapping libraries cannot model:
- Positional elements
- Loop semantics
- Conditional segment selection
- Partner-specific overlays
Result: brittle integrations and hidden drift.
Lack of Structural Testing
When fields are:
- Added
- Removed
- Deprecated
- Renamed
Mappings silently degrade. Most systems cannot answer:
- “Are all required fields mapped?”
- “Which projections break if this field changes?”
- “What views depend on this join?”
Result: production failures instead of build-time detection.
Ad Hoc Query Construction
Query logic lives in:
- String builders
- Raw SQL
- LINQ with leaky abstractions
- Elastic JSON DSL
LINQ hides backend constraints. String queries are unvalidated.
Result: unpredictable behavior and fragile performance.
Manual Materialization & Dependency Tracking
Materialized views and index projections require:
- Custom rebuild logic
- Triggers or pipelines
- Hardcoded dependency tracking
Dependency analysis is usually implicit.
Result: operational fragility and slow evolution.
Ad Hoc Evolution Strategies
When schemas evolve, most systems rely on:
- Manual migration scripts
- Temporary dual-write / dual-read logic
- Hard-coded backfills
- Shadow DTOs
- “V2” types scattered through the codebase
Field renames, splits, type changes, and deprecations are handled reactively and inconsistently. There is rarely a systematic way to answer:
- Which projections are affected?
- Which mappings must change?
- What needs incremental rebuild vs full backfill?
- Is binary compatibility preserved?
Result: fragile migrations, operational risk, and long-lived transitional code.
Cohesive solves this by:
- Treating evolution as a first-class relation
- Supporting version-aware shapes and mappings
- Deriving impacted projections via dependency analysis
- Enabling systematic incremental or rebuild materialization
- Validating coverage and compatibility at build time
Schema evolution becomes declarative, analyzable, and testable — not an ad hoc operational exercise.
Semantic Drift Across Environments
Different environments often evolve differently:
- Dev uses in-memory projections
- Staging uses SQL
- Prod uses Cosmos + Elastic
- Analytics uses Parquet
Subtle differences emerge in:
- Null semantics
- Join behavior
- Aggregation behavior
- Cardinality assumptions
Cohesive solves this by:
- Defining semantics once in IR
- Compiling to backends intentionally
- Providing explain plans
- Making execution strategy explicit
Execution differs. Semantics do not.
What It Provides
Cohesive.Relations makes shape and relational semantics first-class, analyzable, and compilable.
Canonical Shapes
Define your data shape once.
Everything else becomes a projection:
- Storage layout
- API contract
- Search document
- EDI representation
- ML feature vector
- Binary format (Protobuf, Parquet)
No parallel DTO hierarchies. No duplicated semantics.
Declarative, Typed Mapping
Mappings are defined via a typed authoring DSL and compiled to an intermediate representation (IR).
Supports:
- Renames
- Flattening / unflattening
- Type conversions
- Defaults
- Conditional logic
- Nested structures
- Collections
- Partner overlays
- Complex EDI loops and qualifiers
Mappings are:
- Type-checked
- Cardinality-checked
- Version-aware
- Diffable
- Testable
Mapping Coverage & Structural Validation
Cohesive enforces:
- Required fields must be mapped
- Cardinality must match
- Deprecated fields are tracked
- Schema evolution surfaces errors at unit-test time
Silent mapping drift becomes a build failure.
Backend-Aware Query Compilation
Define relations once using semantic IR:
- Filter
- Project
- Join
- Aggregate
- Extend
- Restricted recursion
Compile to:
- SQL
- Cosmos DB
- Elastic
- Gremlin
- In-memory execution
Capability-aligned builders (e.g., CosmosQuery, ElasticQuery) provide static validation of backend constraints instead of hiding them.
var sqlQuery = OrderWithCustomer
.CompileTo(SqlBackend.Instance);
var cosmosQuery = OrderWithCustomer
.CompileTo(CosmosBackend.Instance);
var elasticQuery = OrderWithCustomer
.CompileTo(ElasticBackend.Instance);Decoupled Join Semantics
Join semantics are defined independently of execution semantics.
This enables:
- SQL joins where supported
- Systematic in-memory joins where not
- Partition-aware batching
- Multi-store joins across heterogeneous backends
Relational meaning is preserved. Execution strategy is planned.
var OrderWithCustomer =
Relation.From(Order)
.Join(Customer,on: (o, c) => o.CustomerId == c.Id)
.Project((o, c) => new
{
OrderId = o.Id,
CustomerName = c.Name,
Amount = o.Amount,
Tier = c.Tier
});Systematic Index Projections & View Materialization
Index projections and materialized views are defined as semantic relations.
Cohesive supports:
- Incremental maintenance
- Full rebuild mode
- Dependency graph derivation
- Field-level lineage tracking
Rebuild logic is derived, not handwritten.
var materializedView =
OrderWithCustomer
.Materialize("OrderCustomerIndex")
.WithMode(MaterializationMode.Incremental)
.OrFullRebuild();ML Feature Projections
Relations can define structured feature projections:
- Derived features
- Aggregated statistics
- Time-window metrics
- Nested flattening for vectorization
Feature pipelines remain:
- Versioned
- Dependency-aware
- Reproducible
- Testable
Feature engineering becomes a projection, not a separate system.
Relation.From(Order)
.GroupBy(o => o.CustomerId)
.Aggregate(g => new
{
CustomerId = g.Key,
TotalSpend = g.Sum(x => x.Amount),
OrderCount = g.Count(),
AvgOrderValue = g.Average(x => x.Amount)
});A Structured Intermediate Representation (IR)
At the core of Cohesive.Relations is a small, typed, deterministic intermediate representation (IR) language. All shapes, mappings, projections, joins, and aggregations compile into this IR.
This enables:
- Static validation
- Deterministic execution planning
- Backend compilation
- Dependency graph derivation
- Structural diffing
- Explain plans
Because the IR is:
- Explicit
- Constrained
- Typed
- Composable
It is also well-suited for AI-assisted authoring:
- Language models can propose mapping or projection definitions
- The system validates type, cardinality, and coverage correctness
- Invalid constructs are rejected before execution
LLMs generate candidates. Cohesive proves structural correctness.
External Mapping DSL
Cohesive.Relations supports a declarative external mapping DSL that compiles into the same typed IR as the C# authoring API.
This enables:
- Configuration-driven mappings (EDI, flat files, contracts)
- Loop and qualifier-aware extraction
- Nested and collection mapping
- Partner overlays and versioned mapping sets
Because the DSL compiles to typed IR, it retains full structural guarantees:
- Type and cardinality validation
- Required-field coverage enforcement
- Version-aware evolution checks
- Dependency graph integration
External mappings are not opaque configuration - they are analyzable semantic artifacts, validated and compiled like any other relation.
Incremental Adoption
Don’t be overwhelmed. Start simple:
- Use Cohesive like a typed mapping library.
Then adopt:
- Structural validation
- DSL-based mappings
- Cross-entity joins
- Backend compilation
- ML feature projections
- Materialization
- Dependency analysis
- Recursion
Same semantic core from day one.
Comparison Matrix
Capability | Cohesive.Relations | GraphQL | AutoMapper / Mapster | Manual Mapping | ORM (EF, Hibernate) | SQL / Query Builders |
Canonical shape definition | ✔ First-class IR | ✖ API schema only | ✖ No | ✖ No | Partial (entity model) | ✖ No |
Eliminates DTO sprawl | ✔ Projections from one shape | ✖ | ✖ | ✖ | ✖ | ✖ |
Declarative mapping | ✔ Typed + DSL | ✖ | ✔ (basic) | ✖ | ✖ | ✖ |
EDI / loop-aware mapping | ✔ Native support | ✖ | ✖ | Manual only | ✖ | ✖ |
Mapping coverage validation | ✔ Structural enforcement | ✖ | ✖ | ✖ | ✖ | ✖ |
Cardinality validation | ✔ | ✖ | ✖ | ✖ | Partial | ✖ |
Version-aware evolution | ✔ First-class | Limited | ✖ | Manual | Limited | ✖ |
Field-level lineage / dependency graph | ✔ | ✖ | ✖ | ✖ | ✖ | ✖ |
Backend-agnostic query semantics | ✔ | Partial (API layer) | ✖ | ✖ | ✖ | ✖ |
Backend capability modeling | ✔ Explicit | ✖ | ✖ | ✖ | Limited | ✖ |
Multi-store join support | ✔ Systematic | ✖ | ✖ | Manual | ✖ | ✖ |
In-memory join planning | ✔ Explicit strategy | ✖ | ✖ | Manual | Implicit | ✖ |
Materialized view derivation | ✔ Incremental + rebuild | ✖ | ✖ | Manual | Limited | Manual |
Restricted recursion (CTE / graph) | ✔ | ✖ | ✖ | Manual | Limited | SQL-only |
ML feature projections | ✔ First-class | ✖ | ✖ | Manual | ✖ | Manual |
Compile to Elastic DSL | ✔ | ✖ | ✖ | Manual | ✖ | ✖ |
Compile to Cosmos SQL | ✔ | ✖ | ✖ | Manual | ✖ | ✖ |
Compile to Protobuf / Parquet | ✔ | ✖ | ✖ | ✖ | ✖ | ✖ |
LLM-safe authoring target | ✔ Typed IR | ✖ | ✖ | ✖ | ✖ | ✖ |
Explain plan / execution visibility | ✔ | ✖ | ✖ | ✖ | Limited | Limited |
Structural diffing of mappings | ✔ | ✖ | ✖ | ✖ | ✖ | ✖ |
The Big Idea
Entities, fields, and relationships are first-class. A projection is not copying data. A query is not filtering objects. A mapping is not assigning properties. They are all instances of:
A relation between structured observations over entities.
Relations are declarative, composable, and storage-agnostic.
Cohesive.Relations:
- Unifies mapping, projection, querying, and transformation
- Separates semantics from execution
- Supports incremental adoption
- Scales from DTO mapping to ML pipelines
It is the relational backbone of Semantic Systems Engineering.