Changing Query Types
Gremlinq's query interfaces form a hierarchy — IVertexGremlinQuery<T> is more specific than
IElementGremlinQuery<T>, which is more specific than IGremlinQuery<T>. Three families of
methods let you move through that hierarchy at compile time, without emitting any Gremlin step.
| Purpose | Gremlin emitted | |
|---|---|---|
Lower() |
Steps down to the next less-specific interface | (nothing) |
Force*() |
Changes the interface type and projection hint | (nothing) |
AsAdmin().ChangeQueryType<T>() |
Direct switch to any built-in Gremlinq interface | (nothing) |
Lower()
Lower() returns the next less-specific interface in the hierarchy. The exact return type depends
on the starting point:
| Starting type | Result of Lower() |
|---|---|
IVertexGremlinQuery<T> |
IElementGremlinQuery<T> |
IEdgeGremlinQuery<T> |
IEdgeOrVertexGremlinQuery<T> |
IArrayGremlinQuery<…> |
IGremlinQuery<T[]> |
IGremlinQuery<T> |
IGremlinQuery<T> (no-op) |
The most common use is obtaining a shared base type when two branches of a Union() have
different specific types, or when a DSL extension method requires a less-specific interface.
Lower on a vertex query
Lower on an edge query
Force*()
The Force*() family changes both the C# interface type and the projection metadata that
controls how Gremlinq deserializes results. They are available on any IGremlinQueryBase<TElement>
and do not emit a Gremlin step.
| Method | Return type |
|---|---|
ForceBase() |
IGremlinQuery<TElement> |
ForceVertex() |
IVertexGremlinQuery<TElement> |
ForceEdge() |
IEdgeGremlinQuery<TElement> |
ForceElement() |
IElementGremlinQuery<TElement> |
ForceValue() |
IGremlinQuery<TElement> (value projection) |
ForceProperty() |
IPropertyGremlinQuery<TElement> |
ForceValueTuple() |
IMapGremlinQuery<TElement> |
ForceArray() |
IArrayGremlinQuery<TElement[], TElement, …> |
ForceInEdge<TIn>() |
IInEdgeGremlinQuery<TElement, TIn> |
ForceOutEdge<TOut>() |
IOutEdgeGremlinQuery<TElement, TOut> |
ForceEdge<TOut, TIn>() |
IEdgeGremlinQuery<TElement, TOut, TIn> |
ForceVertexProperty<TValue>() |
IVertexPropertyGremlinQuery<TElement, TValue> |
ForceVertexProperty<TValue, TMeta>() |
IVertexPropertyGremlinQuery<TElement, TValue, TMeta> |
A typical use case is re-establishing the correct interface type after an operation that strips
specialisation — for example ForceBase(), or after constructing steps via AsAdmin().
ForceEdge<TOut, TIn>() is also the right tool when you need the three-parameter edge variant
that records both incident vertex types.
Stripping and restoring vertex semantics
Fully parameterizing an edge query with vertex types
Warning
Force*() only changes the C# type and the deserialization hint — it does not filter the
graph. Use OfType<T>() when you need a server-side hasLabel(…)
filter.
AsAdmin().ChangeQueryType<T>()
AsAdmin() is available on every query object and exposes IGremlinQueryAdmin, which provides
ChangeQueryType<TTargetQuery>(). The only constraint is
where TTargetQuery : IStartGremlinQuery, making it the broadest possible type change.
Force*() and Lower() cover most situations. Use ChangeQueryType<T>() when you need a
specific Gremlinq query interface that neither produces — for example, switching between
two well-known Gremlinq interfaces that have no direct coercion path. The target type must be
one of the interfaces already implemented by Gremlinq's internal query type; arbitrary
user-defined interfaces are not supported.
Direct type change via ChangeQueryType
IGremlinQueryAdmin also exposes AddStep<TTargetQuery>(), ConfigureSteps<TTargetQuery>(),
ConfigureMetadata<TTargetQuery>(), and GetSource() for advanced step-level query construction
in DSL extension methods.