ADR-0012: EF query adapter and initial compatibility boundary¶
Date: 2026-10-11. Status: accepted, initial M1 query subset verified locally; later support expansions require new tests.
The first live EF query proves the pinned EF 10 structural materializer can consume a provider-built ValueBuffer. Use InjectStructuralTypeMaterializers and EF property indices. The provider does not instantiate its own tracker or attach driver-mapped objects. Query compilation/cache and result cardinality remain EF-owned.
The initial supported model uses explicit ToGraphNode labels and optional HasGraphPropertyName mappings, ASCII identifier tokens, and application-owned keys. A finalized-model cache holds only immutable storage projections; per-context drivers and sessions are never captured by it. Supported built-in scalars are string/int/long/double/bool, Guid represented by canonical D strings, and enums represented by checked Int64 values, with nullable variants and explicit EF scalar converters. Unsupported complex/owned/inherited/navigation models fail validation.
The official driver's session/transaction path is asynchronous. Synchronous entity enumeration, synchronous connectivity and persistence throw explicitly for now; ToQueryString can compile synchronously without executing transport. This limits the advertised EF subset but avoids concealed blocking adapters. Streaming enumerators own their sessions and reuse a context transaction when that service is implemented.
Driver session APIs do not accept CancellationToken. Observe cancellation at operation boundaries and complete cleanup; do not abandon in-flight writes or commits with Task.WaitAsync. Immediate interruption of an in-flight driver operation is not promised.
LINQ operations needing nested query stages are rejected until a correct Cypher representation exists. In particular, filtering/ordering/aggregating after paging, repeated Take and Skip-after-Take are not reordered. Unsupported predicates never fall back to client filtering. Nullable ordering is explicit so server null placement matches the selected LINQ semantics. General string ordering follows Neo4j collation; culture-specific CLR ordering is not claimed.
Node persistence and explicit transactions remain separately gated by M2. Database creation/deletion do not run implicit DDL. Later native edge support must first observe actual EF join entries and extend model validation deliberately.