Known limitations¶
GraphBridge supports a tested subset of EF Core and Cypher. Anything outside it is refused with an exception before any database work: a query is never moved to the client and evaluated over a whole graph. This page lists the common limits, the supported alternative for each, and the refusal codes. Compatibility lists what is supported.
Common limitations¶
| Operation or symptom | Current limit | Supported alternative |
|---|---|---|
SaveChanges(), ToList() and other synchronous enumeration |
Persistence and query enumeration are async only; pending synchronous writes throw NotSupportedException. EF can return 0 without provider work when nothing changed |
SaveChangesAsync, ToListAsync, await using. ToQueryString() is offline and can be called synchronously. See the async-only decision |
Entity or custom-comparer Contains, joins, grouping, Distinct, set operators, Sum/Average, non-integer or relationship Min/Max |
Not translated. Integer Min/Max on ordinary nodes and bounded scalar Contains are supported |
Fluent Cypher or reviewed native Cypher |
Row-dependent client methods or arithmetic in Select; composition after a DTO projection |
DTO construction from mapped scalars, parameters and nested entities is supported; arbitrary computed expressions are refused | Filter and order before the projection, or use native Cypher with an explicit projector |
Take(...).Where(...), filtering or ordering after paging, repeated Take |
Refused when the server order cannot be preserved | Filter and order before paging when that keeps your meaning; otherwise native Cypher |
Nested, filtered, multiple or string Include |
One direct native-reference Include is supported (references); association and identified-relationship Include are not |
Query the relationship or node roots explicitly, or a second query by key |
| Required foreign-key reassignment, moving a relationship to other endpoints | Required references and tracked relationship endpoints keep their identity | Optional references support parent changes. Otherwise replace the relationship with a new key or use a reviewed migration; changing an endpoint key does not move a relationship |
| Missing key constraints or duplicate graph identities | Saves require reviewed uniqueness constraints; malformed identities are refused | Inspect and deploy a reviewed schema change (schema and migrations). Queries and saves never repair schema or data |
ReloadAsync, GetDatabaseValuesAsync |
Their projection is refused | Read in a fresh context. Rollback does not rewind values EF already accepted (transactions) |
| Retry after a lost commit acknowledgement | A connection error does not prove rollback; there is no automatic retry or exactly-once guarantee | Check durable state with application IDs in a fresh context first (recovery) |
| Owned, complex or inherited entities; arbitrary converter operations | Unsupported mappings are refused; a conversion does not prove operator equivalence | Explicit graph entities and scalars with reversible conversions; check the specific comparison or ordering (nulls, types and time) |
ExecuteUpdateAsync, ExecuteDeleteAsync |
At most 10,000 selected rows, scalar setters only; keys, endpoints, Include and projected roots are refused; tracked entities are not updated |
Bulk mutations; a failure aborts the whole current transaction |
Refusal codes¶
A refused LINQ query throws Neo4jQueryTranslationException before any database work. Its message names the shape in LINQ terms, a stable code and a supported alternative, for example GraphBridge cannot translate GroupBy [GBQ101]. Group in Fluent Cypher with With(...) .... The code is in the exception's Code property and in Exception.Data["GraphBridge.QueryDiagnostic"], and Doctor reports it as the subcode of GBD-QUERY-001. Match on the code, not the message text. Fluent Cypher refusals throw FluentCypherException with GBFC codes (Fluent Cypher).
| Code | Refused | Supported alternative |
|---|---|---|
| GBQ100 | Other unsupported shapes, such as unmapped roots or properties | The documented subset, or a reviewed native query |
| GBQ101 | GroupBy |
Fluent Cypher With(...) with Graph.Count, Min, Max, Sum or Avg, or grouping a bounded list in memory |
| GBQ102 | Distinct |
Fluent ReturnDistinct, or de-duplicating a bounded projected list |
| GBQ103 | Join, GroupJoin, LeftJoin, RightJoin, SelectMany |
Match the relationship in Fluent Cypher, or query each side and join a bounded result |
| GBQ104 | Union, Concat, Intersect, Except |
Separate queries combined in memory, or a reviewed native query |
| GBQ105 | Sum, Average, and Min/Max beyond direct int/long properties |
Fluent Graph.Sum, Avg, Min, Max, or integer aggregates |
| GBQ106 | Last, Reverse, ElementAt, SkipWhile, TakeWhile |
Opposite ordering with First, or Skip(n) with First |
| GBQ107 | OfType, Cast |
The mapped type's own DbSet |
| GBQ108 | All, DefaultIfEmpty |
Any with the opposite condition, or Fluent OPTIONAL MATCH |
| GBQ110 | Operators after Skip/Take, repeated Take, operators after a scalar projection |
Apply operators before paging or projecting, or split the query |
| GBQ120 | Methods or computation over entity members, unsupported predicate operators and converter comparisons; correlated subqueries and collection navigations in a filter, such as Where(p => p.Pets.Any()) or Where(p => db.Pets.Any(x => x.OwnerId == p.Id)); a vector property in a predicate other than a null test, or in ordering |
Compare mapped scalars with variables or constants; match the relationship in Fluent Cypher; typed vector search for similarity |
| GBQ130 | Unsupported Contains shapes |
Contains over a captured array or List<T> of supported scalars (at most 1,024) |
| GBQ140 | Nested, filtered, multiple or string Include |
One direct native-reference Include, or a second query by key |
| GBQ150 | Projections beyond mapped scalars and DTOs, including subqueries in a projection | DTO projections |
| GBQ160 | Unsupported ExecuteUpdateAsync/ExecuteDeleteAsync shapes |
Direct scalar setters on a mapped entity root (bulk mutations) |
| GBQ170 | Aggregates over association, identified-relationship or native-reference roots | Aggregate the related node set, or a reviewed native query |
Fluent Cypher codes¶
A refused Fluent query throws FluentCypherException, a NotSupportedException whose Code holds the code below, before any database work (Fluent Cypher). The message names the exact shape and the alternative.
| Code | Refused | Supported alternative |
|---|---|---|
| GBFC101 | A lambda shape with no faithful translation: method calls, arithmetic, client computation, list membership on a stored list | A comparison, null test, values.Contains(member), ordinal StartsWith/EndsWith/Contains, or the explicit predicate methods |
| GBFC102 | A captured value that C# would reject, or that reading could run application code: a null for a non-nullable type, a null collection, a computed operand | Assign the value to a local variable first, and pass non-null values |
| GBFC103 | A comparison without a symbol member, or of whole symbols | Compare alias.Value.Member or a WITH value |
| GBFC104 | ! over a predicate that can be null |
.Not() on the explicit predicate, or an explicit null test |
| GBFC105 | A value that can't be compared exactly: a lossy conversion, overflow, NaN in a list, a user-defined operator | A value of the property's own type |
| GBFC106 | Culture-sensitive or case-ignoring string comparisons | StringComparison.Ordinal, or the explicit .StartsWith(...) methods |
| GBFC107 | Contains with a custom comparer, over another collection type, or with more than 1,024 values |
An array, List<T> or HashSet<T> with default equality; batches |
| GBFC110 | ==, != or Contains where null makes C# and Cypher disagree |
.Eq(...), .Ne(...) with explicit IsNull()/IsNotNull() |
| GBFC111, 113 | Text operators, ordering or WITH comparisons over converted properties; comparing two converted properties |
An unconverted representation, or a reviewed native query |
| GBFC112 | Temporal comparisons and membership in C# | The explicit .Gt(...), .In(...) predicate methods |
| GBFC114 | A vector property used other than returned or tested for null | Graph search, or a search that starts the query |
| GBFC150 | An ordering key that isn't a member, a WITH value, or isn't returned |
Order by a returned member or value |
| GBFC201, 214 | A bounded pattern without a named path, or with more steps | Match(path, pattern.Repeat(min, max)) with one step |
| GBFC202 | An undirected step outside a named bounded path | A named bounded path |
| GBFC203 | A bounded or undirected pattern over a heterogeneous mapping, or over a relationship type that several entity types map | A directed single step, or a reviewed native query |
| GBFC204, 206, 207, 208 | Rebinding a path, a dropped symbol or a repeated edge; reusing an edge with other endpoints | A new symbol |
| GBFC205, 209, 210, 211 | Endpoints that aren't node symbols, unmapped relationships, a direction that contradicts the mapping, a type mapped more than once | Symbols of mapped types, in the mapping's direction |
| GBFC212 | A type with EF query filters | LINQ, which applies them, or a reviewed native query |
| GBFC213 | A property selector that isn't one direct mapped property, or a derived reference key | A mapped scalar property, or the relationship itself |
| GBFC301 | A query that doesn't start with MATCH or a search |
Start with Match(...), SearchVector or SearchFullText |
| GBFC302, 303, 304 | WITH beyond forwarding symbols and introducing aggregates; a symbol out of scope; an expression the clause doesn't support |
Forward what later clauses use |
| GBFC305, 306, 307 | A search after another clause, a score that isn't a fresh Cypher.Score(), a Where straight after a search |
Starting from a search |
| GBFC401, 402, 403, 404 | Returns beyond mapped scalars, entities, WITH values and DTOs; constructing a mapped entity |
Return the symbol, Return(() => movie.Value), or a DTO |
| GBFC405 | ORDER BY of something not returned |
Return it too |
| GBFC406 | An aggregate of anything but a mapped, unconverted property | alias.Property(p => p.Year) |
| GBFC407 | A returned predicate that can be null, read as bool |
(bool?)Graph.Is(...) |
| GBFC408 | An entity storing a property under GraphBridge's reserved prefix, returned whole | Its scalar members |
Reporting a limitation¶
Model mapping errors come from model validation; query refusals from the unsupported-method visitor. When you report one, include a small synthetic model, the LINQ shape, the refusal code, exact versions and the exception type. Remove credentials and application values. The behavior matrix maps each supported behavior to its tests.
Try it¶
Workshop lesson 06 · The failure lab triggers the common refusals and shows each code and alternative.