Cohesive Systems logoCOHESIVE SYSTEMS

Search Cohesive Systems

Ready

Search Cohesive Systems

Find product pages, building blocks, technical articles, and graph definitions.

Building Blocks

Cohesive.Relations

Portable relational programming for mapping, hydration, querying, and derived data across heterogeneous systems.

Core Idea

SQL showed the value of describing facts, relationships, filters, projections, and aggregations without prescribing the execution algorithm. Its usual boundary is a particular database catalog, server, dialect, and runtime.

Cohesive.Relations brings that declarative character into a general-purpose programming environment. Facts may come from PostgreSQL, Cosmos DB, a search index, an API, supplied CLR objects, observations, caches, or several sources together. The relational meaning stays portable while compilers, planners, and runtimes decide how to realize it.

A typed authoring surface can express a rooted derivation from a load and its related carrier into a search document:

var loadSearchDocument = Relation<LoadSearchDocument>
    .From<Load>()
    .Join<Carrier>((load, carrier) => load.CarrierId == carrier.Id)
    .Select((load, carrier) => new LoadSearchDocument
    {
        LoadId = load.Id,
        CarrierName = carrier.LegalName,
        Amount = load.TotalAmount,
        CarrierSafetyScore = carrier.SafetyScore
    });

The code defines the relation, not its physical execution. If Load and Carrier are available through one relational backend, a compiler can lower it to a single SQL query. If they live in different stores, the same definition can compile into a coordinated cross-source acquisition and hydration plan that batches lookups, joins the resulting facts, and produces the same LoadSearchDocument. The semantic contract stays fixed; only its realization changes.

Portable Relational Programming

Relational programming describes which facts, combinations, and derived values hold without reducing the program to one execution plan.

SQL offers the most familiar version of that idea, but normally assumes that the facts already live inside one database boundary. LINQ brings query structure into application code, but execution still depends on local sequence semantics or a provider's translation limits.

Cohesive.Relations keeps the semantic program above those choices. A logical source says that facts of a particular shape are available. It does not decide whether they arrive from memory, storage, a remote service, a cache, a materialized view, or a composed cross-source plan.

That separation gives relational definitions several forms of portability:

  • Data-source portability: facts can come from local objects, observations, repositories, databases, indexes, APIs, or several systems together.
  • Target portability: the same logical operators can be interpreted by SQL, document, graph, search, and in-memory runtimes.
  • Purpose portability: the model can support execution, validation, optimization, lineage, documentation, migration analysis, and diagnostics.

Mental Model

Cohesive relational programs connect several related concepts. A fact is a shaped value, often represented as an observation. A relation and a query use those facts differently.

Fact

Meaning
A shaped value available to a relational program.
Typical role
A CLR object, database row, observation, API result, cached value, or materialized document.

Relationship

Meaning
A named semantic connection between facts.
Typical role
Reference traversal, hydration, dependency analysis, navigation, or incremental impact tracking.

Derivation

Meaning
A declaration of how new facts can be established from available facts.
Typical role
Mapping, enrichment, denormalization, aggregation, reconciliation, or feature construction.

Relation

Meaning
A reusable derivation rooted in an input value.
Typical role
DTO mapping, hydration, lineage, incremental maintenance, and output cardinality per root.

Query

Meaning
An independently invoked request over a logical relational graph.
Typical role
Retrieval, search, reporting, exploration, ordering, paging, and aggregation.

Relationships Are More Than Joins

A relationship such as Load.CustomerId → Customer identity is part of the semantic relation model. It records which shaped facts are connected and preserves the identity, direction, cardinality, requiredness, lineage, and dependency meaning of that edge.

Forward traversal from one Load.CustomerId may yield at most one customer. Inverse traversal may yield many loads. A required reference means the key must be present; it does not claim that the referenced observation currently exists.

An interpreter can realize that relationship in several ways:

  • SQL join
  • Cosmos point read
  • Batched lookup
  • Cache lookup
  • Graph-edge traversal
  • In-memory hash join

An explicit join is still useful when two independently produced rowsets need to be correlated by a predicate. But it should only be treated as a declared relationship when it can preserve the complete relationship semantics.

Relations and Queries

Relations and queries share a logical algebra because both describe relational computation:

  • Source
  • Filter
  • Traverse relationship
  • Join
  • Expand collection
  • Project
  • Distinct
  • Aggregate
  • Order
  • Page

They differ in the contract wrapped around that shared logical graph:

Purpose

Relation
Reusable correspondence or derivation.
Query
Independently invoked request for results.

Root

Relation
Rooted in an input value.
Query
Rooted in one or more named result branches.

Output

Relation
Declares output shape, cardinality per root, identity, and invariants.
Query
Declares row or aggregation results, parameters, ordering, and paging.

Evaluation

Relation
Can be reused or evaluated incrementally as facts change.
Query
Normally evaluated in response to an invocation.

Primary uses

Relation
Mapping, enrichment, hydration, denormalization, lineage, and dependency analysis.
Query
Retrieval, search, reporting, exploration, and aggregation.

The distinction is semantic rather than physical. Neither definition chooses a database, source placement, join algorithm, batching strategy, or execution runtime.

Aggregation and Result Branches

Aggregation is part of the query model, not a separate reporting API layered onto it. Filters, relationship traversals, joins, projections, and aggregations can share the same logical graph, so one query can expose several named views of the same predicate scope.

One predicate scope can feed several query results

Shared sources, joins, and predicates is the shared source for rows — projection, ordering, and paging, totals — count, sum, min, and max, by customer — grouping and filtered measures.

Rows and aggregations are distinct named result branches over shared relational meaning.

An aggregate node turns an input rowset into a shaped result. With no grouping fields it produces a singleton summary. With one or more grouping fields it produces a row per distinct key. Each aggregate assignment names its target field, operation, value expression, and optional filter.

  • Count
  • Sum
  • Min
  • Max
  • Any
  • All

Because aggregate output is itself a semantic shape, it can be projected, ordered, and paged like other query results. A single query might therefore return a page of delayed loads, an overall delayed-load count, and totals grouped by customer without duplicating the shared filter and join definitions.

An interpreter can lower the complete graph to a native SQL or backend aggregation when the target supports it. When data or capabilities are divided across sources, a planner can push compatible work into each source and compose the remaining aggregation. Unsupported semantics must be diagnosed rather than silently changed.

Authoring and Canonical IR

The canonical relationship catalog and relation/query IR are the sources of semantic truth. C# DSLs, generated definitions, importers, visual tools, and inference systems are producers of those portable models.

Relationships are persisted independently with stable identities. Relation and query definitions reference those relationships from a shared logical node graph. Versioned documents, strict validation, stable identifiers, and deterministic fingerprints make the model durable and inspectable outside one process or host language.

Inferred or convention-authored relations may begin as drafts. A draft can preserve candidate assignments, ambiguity, and explicit omissions without pretending that incomplete work is executable. Semantic acceptance checks output coverage, field existence, type compatibility, cardinality, presence, and nullability before producing an accepted relation.

Authoring

Produce

Typed DSLs, generated definitions, importers, visual tools, and Ari introduce relational intent.

C# DSLAriimportstooling

Definition

Draft or Declare

Direct declarations or portable drafts capture logical structure, assignments, candidates, and omissions.

nodesbindingscandidatesresolutions

Validation

Accept

Shape-aware analysis checks coverage, types, cardinality, presence, nullability, and invariants.

coveragetypescardinalityinvariants

Canonical IR

Persist

Versioned relationship catalogs and relation/query definitions retain stable identities and fingerprints.

catalogrelationqueryprovenance

Realization

Interpret

Analyzers, compilers, planners, and runtimes execute, validate, visualize, document, or explain the model.

compileplanexecuteexplain
Draft uncertainty is resolved before canonical acceptance. Runtime acquisition and execution choices happen later as interpretations of the accepted portable model.

This keeps authoring uncertainty separate from accepted semantics and from runtime input availability.

Ari and Schema Matching

The simplest DTO mapping copies values between two nearly identical shapes. Customer.Id maps to CustomerDto.Id; Customer.Name maps to CustomerDto.Name. The field names, types, and structures already agree, so the relation is little more than a set of direct assignments.

Real mappings quickly add structural nuance:

Direct assignment

Source
Customer.Id
Target
CustomerDto.Id
Relational meaning
Copy a compatible value between corresponding fields.

Rename

Source
Customer.LegalName
Target
CustomerDto.Name
Relational meaning
Preserve the correspondence even though the field labels differ.

Flatten

Source
Customer.Address.City
Target
CustomerDto.City
Relational meaning
Project a nested source path into a flatter target shape.

Nest

Source
CustomerDto.City
Target
Customer.Address.City
Relational meaning
Reconstruct a nested target path from a flatter source shape.

Even this is schema matching in a small, unusually convenient form: the two schemas live in the same codebase, their types are already known, and a developer can state each correspondence directly.

Ari extends Cohesive.Relations from explicitly authored mappings to inferred and governed matchings between arbitrarily complex, structurally distinct schemas. A source or target may be deeply nested, repeating, optional, encoded with unfamiliar names, organized around different concepts, or constrained by qualifiers and code sets. Ari analyzes those shapes as semantic graphs and proposes correspondences that may include renames, conversions, flattening, nesting, hierarchy changes, and value-dependent rules.

Those proposals retain confidence, supporting evidence, explanations, alternatives, and review state. A reviewer can accept, reject, constrain, or refine them without confusing inference uncertainty with executable semantics. Once accepted, the matching becomes a portable Cohesive.Relations definition that can be validated, persisted, interpreted, and reused across runtimes.

Required Facts Drive Data Loading

A relation or query declares logical sources, visible bindings, required and optional related inputs, predicates, projections, and output requirements. That semantic structure tells an interpreter which facts and fields are needed without dictating how they must be acquired.

An interpreter can then:

  • Select only fields required by outputs, predicates, joins, ordering, aggregation, invariants, and diagnostics.
  • Push supported filters and projections into a backend.
  • Batch related keys across roots.
  • Hydrate missing facts through repositories, caches, or remote services.
  • Compose native backend work with in-memory joins or projections.
  • Materialize a derived result when repeated acquisition is the wrong realization.

Adapters describe their capabilities and constraints. Compilers compare those capabilities with the relational program and produce a native, composed, constrained, overridden, or unsupported realization. They must not silently weaken semantics.

One Model, Many Interpretations

Authoring and inference produce semantic definitions. Compilers, analyzers, planners, and runtimes interpret them.

Producers

Author or infer

C# DSLs
Ari inference
Importers
Visual and generated tooling

Semantic source of truth

Canonical portable models

Relationship catalog

Stable semantic edges with direction, cardinality, lineage, and dependency meaning.

Relation / query IR

A shared logical graph wrapped in distinct relation and query contracts.

Interpretations

Execute, analyze, or explain

Compiled mapper
SQL or backend query
Hydration or cross-source plan
In-memory evaluator
Index synchronization
Lineage and diagnostics
Visualization and documentation
Authoring surfaces and inference systems produce the semantic model. Compilers, planners, analyzers, and runtimes interpret it while retaining provenance to the canonical definitions.

An interpretation does not have to execute the definition. Validation, optimization, visualization, documentation generation, migration planning, dependency analysis, and lineage reporting are also realizations of the same semantic model.

Derived artifacts should retain provenance to the IR nodes and compiler decisions that produced them.

How It Compares

Cohesive.Relations overlaps with familiar mapping and query tools, but treats the relation or query as a portable semantic asset rather than making one runtime or transport its defining boundary.

AutoMapper / Mapster

Shared ground
Convention-based and explicitly configured object-to-object mapping, including compiled DTO projections.
Cohesive.Relations boundary
DTO mapping is one relational derivation. The definition can also preserve multiple sources, joins, required facts, output cardinality, lineage, hydration, and interpretations beyond an object mapper.

GraphQL

Shared ground
A uniform query language and resolver graph that can compose heterogeneous data sources behind one API.
Cohesive.Relations boundary
GraphQL defines a client-facing remote API contract. Cohesive.Relations defines a transport-independent semantic protocol for application components; Cohesive.Api can expose it through GraphQL or another API surface.

LINQ

Shared ground
Queries expressed in application code and interpreted by different providers or by in-memory execution.
Cohesive.Relations boundary
It shares LINQ's goal of separating query expression from interpretation, while adding a canonical, persistable IR with explicit source requirements, relationships, result contracts, and target capabilities.

ORMs

Shared ground
Database querying, relationship loading, object materialization, persistence, and change tracking.
Cohesive.Relations boundary
It does not assume one persistence model or track changes. Facts may come from supplied objects, observations, repositories, databases, APIs, caches, or a composed cross-source plan.

SQL / SQL builders

Shared ground
Precise, composable access to a relational database schema, dialect, and native capabilities.
Cohesive.Relations boundary
It models relational meaning above a particular catalog or dialect. SQL is one possible lowering target rather than the source of semantic truth.

Cohesive.Relations is not intended to replace every use of these tools. It is most useful when the mapping or query needs to remain inspectable and reusable across execution, hydration, persistence, API exposure, materialization, lineage, diagnostics, or multiple infrastructure targets.

Use Cases

Cohesive.Relations applies anywhere software needs to connect facts, derive a shaped result, request relational data, maintain a derived view, or explain why an output exists. Many of these use cases form projection models in the wider system graph.

Build portable read paths

Queries can span stores while preserving selection, batching, ordering, paging, and aggregation semantics.

  • CQRS read-model construction
  • GraphQL and API field resolution with batched loading
  • Reporting datasets and exports
  • Query federation across services and stores

Cohesive.Relations specifies what data a model or agent needs and how that data is loaded, joined, transformed, and projected. Agent behavior, tool use, planning, and orchestration are concerns for Cohesive.Semantics, not the relation model.

Diagnostics and Explainability

A relation or query can explain more than whether it is valid. Because its required facts, relationships, predicates, result branches, and capability requirements remain explicit, a planner can show both why data is needed and why a particular realization was selected.

Derivability Diagnostics

Because mappings and projections are represented as derivations, missing inputs can be explained instead of reduced to a mapper failure:

Cannot derive LoadSearchDocument.CarrierName.Required premises  Load.CarrierId = "carrier-123"  Carrier.Id = "carrier-123"Available:  Load.CarrierIdMissing:  Carrier with Id "carrier-123"

The model keeps three forms of incompleteness separate:

Definition hole

Meaning
A draft assignment is unresolved, ambiguous, or semantically unsafe.
Consequence
Acceptance fails until the definition is resolved or an optional output is explicitly omitted.

Inference uncertainty

Meaning
A producer such as Ari has confidence, alternatives, or evidence that still requires policy or review.
Consequence
The producer retains the evidence and may resolve the draft to selected, ambiguous, or unresolved state.

Runtime input hole

Meaning
An accepted definition cannot acquire a required fact during one evaluation.
Consequence
The runtime emits a hydration or derivability diagnostic without changing the accepted semantics.

Missing, null, absent, unavailable, failed, and not requested are also distinct states. Structured diagnostics can therefore support applications, tests, deployment gates, index-management tools, and developer tooling.

Plan Explanations

Plan explanations connect the semantic definition to its physical realization. They can show:

  • Why each source and field is required.
  • Which filters, projections, or aggregations were pushed into a backend.
  • Why a batched lookup, cross-source join, or in-memory operation was selected.
  • Where ordering, paging, and aggregation execute, including capability-driven fallbacks.
  • Which IR nodes and compiler decisions produced each physical step.
Requested: LoadSearchDocument.CarrierNameRequires:  Carrier.LegalName  Load.CarrierIdCarrier.IdSelected plan:  Read Load.Id, Load.CarrierId, and Load.TotalAmount from Cosmos  Batch distinct CarrierId values  Read matching Carrier facts from PostgreSQL  Hash join in application memory  Project LoadSearchDocumentWhy:  Load and Carrier do not share a native join boundary.  Batched loading preserves the declared relationship with two source reads.

Like a database EXPLAIN result, this traces how a logical request becomes a physical plan. For a portable relation or query, that plan may also include backend capability matching, cross-source data loading, and composed execution.

Why It Matters

Most systems accumulate mapping code, repository hydration, query builders, SQL strings, API response shaping, UI filters, search documents, reporting logic, integration transforms, and index-maintenance jobs as separate artifacts. Each artifact embeds part of the same relational meaning, usually without shared identity or provenance.

Cohesive.Relations makes that meaning first-class.

The payoff is not one universal runtime. It is one portable source of relational meaning that can be authored, inferred, persisted, validated, inspected, and interpreted without losing the distinction between a reusable relation and an invoked query.

Define the relational program once. Interpret it as a mapper, query, hydration plan, materialized view, index synchronizer, lineage report, or explanation while retaining provenance to the semantic source.