DynamicWhere.ex
DynamicWhere.exv3.4.0·docs

FilterResult<T>

FilterResult<T> is the strongly-typed wrapper returned by every terminal filter extension — ToList<T>(Filter), ToListAsync<T>(Filter), and the dynamic variants. It contains the result page plus pagination metadata.

Properties

PropertyTypeDescription
PageNumberintCurrent page (0 when no pagination).
PageSizeintPage size (0 when no pagination).
PageCountintTotal pages. 1 when the query carried no Page — an unpaged result is one page of everything — and 0 when nothing matched.
TotalCountintTotal matching records.
DataList<T>The result entities.
QueryStringstring?Generated SQL (when getQueryString: true is passed to the extension).
PolicyPolicyTrace?What the policy layer did to this query. null unless the query went through ApplyPolicy. A guarded query sets it as DwPolicyOptions.IncludeTraceInResult decides: by default it is present under the convenience tier and null under the strict tier (since 3.1.0 — see breaking changes). The trace is always on PolicyQueryable<T>.LastTrace.
Note
When the input Filter has no Page, PageNumber and PageSize come back as 0 and the full result sits in Data. PageCount is 1 — the one page the whole result occupies — or 0 when nothing matched. With a Page, it is Ceiling(TotalCount / PageSize).
Changed in 3.1.0
An unpaged PageCount used to equal TotalCount: the calculation divided by a page size of 1 whenever none was sent, so a 5,000-row result reported 5,000 pages of one row each. A client that draws a pager straight from PageCount now gets one page instead of one per row. PageNumber and PageSize are unchanged — both still 0 when no page was sent.
A guarded query may be paged for you
On a guarded query, a deployment that sets DwCaps.DefaultPageSize gives a request with no Page page 1 at that size, capped at MaxPageSize, so PageNumber, PageSize and PageCount come back as for any paged request. It never replaces a page the caller sent. A context declaring a purpose with page caps of its own in DwCaps.Purposes takes each of the two caps that purpose sets from it instead (3.4.0).

C# usage

FilterResult<Customer> result = await dbContext.Customers.ToListAsync(filter);

Console.WriteLine($"page {result.PageNumber} of {result.PageCount}");
Console.WriteLine($"{result.TotalCount} total matches");

foreach (var customer in result.Data)
{
    Console.WriteLine($"- {customer.Name}");
}

JSON response example

{
  "pageNumber": 1,
  "pageSize": 10,
  "pageCount": 5,
  "totalCount": 42,
  "data": [
    { "id": 7, "name": "John Doe", "createdAt": "2025-09-14T12:31:00Z" },
    { "id": 8, "name": "Jane Roe", "createdAt": "2025-09-13T08:11:00Z" }
  ],
  "queryString": null,
  "policy": null
}

See also