Skip to content
FlexQuery.NET

Query Options

QueryOptions (namespace FlexQuery.NET.Models) is the parsed form of a request — the single model every execution method consumes, regardless of where the request came from (query string, fluent builder, or adapter). Understanding its properties means understanding everything the pipeline can do.

How a request becomes options

Three equivalent paths, one destination:

C#
// 1. From FlexQueryParameters (query-string binding)
var options = parameters.ToQueryOptions();                    // global default syntax
var options2 = parameters.ToQueryOptions(QuerySyntax.Fql);    // explicit syntax

// 2. Built in code (fluent API)
var options4 = Query.Create()
    .Filter(f => f.Equal("Status", "Active"))
    .Page(1, 20)
    .Build();

Most endpoints skip explicit construction entirely — FlexQueryAsync(parameters, ...) converts internally. Constructing QueryOptions yourself matters when composing: adapter output, pre-built saved queries, or merging client input with server-side structure.

Properties

PropertyTypeDescription
FilterFilterGroup?Filter expression tree — conditions, nested groups, logic operators. See Filtering.
SortList<SortNode>Ordered sort specs (field, direction, optional aggregate). See Sorting.
SelectList<SelectNode>?Projection tree — fields, aliases, nested selections. See Projection.
IncludesList<string>?Navigation paths to include with all scalars. See Include.
ExpandList<IncludeNode>?Expansion trees with per-branch filter/sort/take. See Expand.
ProjectionModeProjectionModeOutput shaping: Nested (default), Flat, FlatMixed.
GroupByList<string>?Group key fields.
AggregatesList<Aggregate>Aggregate specs (typed AggregateFunction + field + alias).
HavingHavingNode?Condition tree over aggregate values — functions referenced as FUNCTION:Field:Operator:Value (e.g. sum:Total:gt:100), which must match a declared aggregate.
Distinctbool?Applies Distinct().
PagingPagingOptionsPage, PageSize (clamped 1–1000), Disabled flag.
IncludeCountbool?Whether the total count is computed.

The three request models

ModelUse when
FlexQueryParametersASP.NET Core [FromQuery] binding of raw strings.
FlexQueryRequestStrongly-typed request objects (OpenAPI-documented bodies), via ToQueryOptions().
QueryOptionsComposed server-side, adapter output, saved queries.

Projection modes in detail

ModeBehavior
NestedNested selections produce nested objects — the natural hierarchical shape.
FlatNested collections flatten with SelectMany into a leaf-level rowset (SQL-join semantics).
FlatMixedRoot scalars and nested-collection fields share one output row.

Complete worked example

Composing client input with server-side constraints:

C#
[HttpGet("api/orders/search")]
public async Task<IActionResult> Search(
    [FromQuery] FlexQueryParameters clientParams,
    CancellationToken cancellationToken)
{
    var options = clientParams.ToQueryOptions();   // client-driven part

    // server-side composition - clients cannot override these
    options.GroupBy = ["Status"];
    options.Aggregates.Add(new Aggregate
    {
        Function = AggregateFunction.Sum,
        Field = "TotalAmount",
        Alias = "TotalRevenue",
    });

    var result = await db.Orders.FlexQueryAsync(options, cancellationToken);
    return Ok(result);
}

Common mistakes