Extension Methods
Every extension method lives in DynamicWhere.ex.Source.Extension and operates on IQueryable<T> — with IEnumerable<T> overloads for in-memory variants. The methods fall into four intents: projection, filtering, composition, and materialization.
Projection
Project a query into a typed shape or a dynamic shape. Both support direct properties, whole navigation objects, whole collections, and dotted paths through reference and collection navigations.
| Method | Signature | Returns | Async | Link |
|---|---|---|---|---|
Select | .Select<T>(List<string> fields) | IQueryable<T> | No | Docs |
SelectDynamic | .SelectDynamic<T>(List<string> fields) | IQueryable | No | Docs |
Filtering
Build the where-clause, group, order, or paginate the query — one building block at a time.
| Method | Signature | Returns | Async | Link |
|---|---|---|---|---|
Where | .Where<T>(Condition condition) | IQueryable<T> | No | Docs |
Where | .Where<T>(ConditionGroup group) | IQueryable<T> | No | Docs |
Group | .Group<T>(GroupBy groupBy) | IQueryable | No | Docs |
Order | .Order<T>(OrderBy) / .Order<T>(List<OrderBy>) | IQueryable<T> | No | Docs |
Page | .Page<T>(PageBy page) | IQueryable<T> | No | Docs |
Composition
Apply a complete Filter or Summary composition to the query. Each returns an IQueryable so you can chain further operations before materializing.
| Method | Signature | Returns | Async | Link |
|---|---|---|---|---|
Filter | .Filter<T>(Filter filter) | IQueryable<T> | No | Docs |
FilterDynamic | .FilterDynamic<T>(Filter filter) | IQueryable | No | Docs |
Summary | .Summary<T>(Summary summary) | IQueryable | No | Docs |
Materialization
Execute the composed query and return a paginated result — typed, dynamic, summary, or segment. The async terminals count with EF Core's CountAsync and read with EF Core's ToListAsync. Since 3.2.0 that includes the dynamic Filter's read and the Summary's count and read: the count used to run synchronously, and the reads through Dynamic LINQ, with no token to pass on. ToListAsync(Summary) on a provider that is not EF Core's keeps its synchronous count and Dynamic LINQ's read, and ToListAsync(Segment) combines its sets into one query and then counts and reads it exactly as a Filter does.
| Method | Signature | Returns | Async | Link |
|---|---|---|---|---|
ToList (Filter) | .ToList<T>(Filter, bool getQueryString = false) | FilterResult<T> | No | Docs |
ToListAsync (Filter) | .ToListAsync<T>(Filter, bool getQueryString = false) | Task<FilterResult<T>> | Yes | Docs |
ToListAsync (Filter, token) | .ToListAsync<T>(Filter, CancellationToken) / .ToListAsync<T>(Filter, bool getQueryString, CancellationToken) | Task<FilterResult<T>> | Yes | Docs |
ToListDynamic (Filter) | .ToListDynamic<T>(Filter, bool getQueryString = false) | FilterResult<dynamic> | No | Docs |
ToListAsyncDynamic (Filter) | .ToListAsyncDynamic<T>(Filter, bool getQueryString = false) | Task<FilterResult<dynamic>> | Yes | Docs |
ToListAsyncDynamic (Filter, token) | .ToListAsyncDynamic<T>(Filter, CancellationToken) / .ToListAsyncDynamic<T>(Filter, bool getQueryString, CancellationToken) | Task<FilterResult<dynamic>> | Yes | Docs |
ToList (Summary) | .ToList<T>(Summary, bool getQueryString = false) | SummaryResult | No | Docs |
ToListAsync (Summary) | .ToListAsync<T>(Summary, bool getQueryString = false) | Task<SummaryResult> | Yes | Docs |
ToListAsync (Summary, token) | .ToListAsync<T>(Summary, CancellationToken) / .ToListAsync<T>(Summary, bool getQueryString, CancellationToken) | Task<SummaryResult> | Yes | Docs |
ToListAsync (Segment) | .ToListAsync<T>(Segment segment) | Task<SegmentResult<T>> | Yes (only) | Docs |
ToListAsync (Segment, token) | .ToListAsync<T>(Segment, CancellationToken) | Task<SegmentResult<T>> | Yes (only) | Docs |
ToListAsync and ToListAsyncDynamic with a Filter, ToListAsync with a Summary and ToListAsync with a Segment each have overloads that take a CancellationToken. The token reaches the count and the read. The overloads sit beside the 3.1 signatures, which are unchanged, so code compiled against 3.1 still binds. ToListAsync(filter, default) no longer compiles, because default fits both getQueryString and the token; neither do ToListAsyncDynamic(filter, default) and ToListAsync(summary, default). Write false, a token, or a named argument. And a reflection lookup of ToListAsyncDynamic by name alone now finds three methods where it found one: pass the parameter types to Type.GetMethod.ToList<T>(Segment) variant. The set operations (Union / Intersect / Except) combine every ConditionSet into one query, which the database orders and pages.In-memory overloads
Exactly three of the terminals also expose an IEnumerable<T> overload — ToList(Filter), ToListDynamic(Filter) and ToList(Summary). These wrap the collection with AsQueryable() and delegate to the typed overload — handy for unit tests and in-process pipelines. Nothing else has one: there is no ToListDynamic(Summary), and no async or composable method works on an IEnumerable<T> source. Counting those three and the seven overloads that take a CancellationToken, the library ships 28 extension methods.
getQueryString: true to any Filter or Summary materialization call to capture the generated SQL on the result. .ToListAsync<T>(Segment) takes no such parameter, so SegmentResult<T>.QueryString is always null. The call reaches EF Core's .ToQueryString(), so on a non-EF Core source the property holds a placeholder sentence rather than SQL.[DwEntity(RequirePolicy = true)] throws PolicyException with PolicyRequired when it is reached through any of them without ApplyPolicy. Plain LINQ on the same DbSet is not intercepted — the guard covers this library's methods, not Entity Framework Core's.