Choose by the identity of each row#
Use ordinary CRUD for an entity's generated record experience. Use query-backed CRUD when every displayed row still identifies one authoritative entity but the worklist needs a joined, calculated or service-shaped read model. Use Reporting when rows have an independent aggregation or grouping grain. SQL versus LINQ does not determine the module.
| Experience | Read model | Write authority |
|---|---|---|
| Ordinary CRUD | Entity metadata and supported provider queries | Authorized entity mutation boundary |
| Named CRUD experience | Selected grid/forms and optional trusted predicate | Existing entity mutation boundary |
| Query-backed CRUD | Typed projection mapped to entity keys | Fresh authoritative entity read, command or form |
| Custom Razor page | Consumer-owned service model | Consumer-owned protected operation |
Configure differences from generated defaults#
The generated default experience uses default profiles. Named experiences select grid, create, edit and details profiles, labels and optional query scopes. Adding Menu(...) opts an experience into navigation; omitting it does not itself revoke execution permission.
A trusted QueryScope is a provider-translatable entity predicate. It narrows that experience's query before filters, counts and paging. It is application-lifetime configuration and must not capture an actor or scoped service. Other entity, relationship and mutation endpoints do not acquire that predicate automatically. Enforce record and tenant policy at every authoritative execution path.
Web uses AddCrud() and receives the authorized definitions rather than duplicating API profiles. Normal and named routes remain distinct. A missing or incompatible experience must fail closed, without silently querying an unrestricted entity list.
Implement a query-backed worklist#
- Register the named entity experience and a suitable flat grid profile.
- Define typed parameters, projection rows and a trusted server scope type.
- Register
AddMatrixCrudQuery<TParameters, TRow, TScope, THandler, TPolicy>with anAdminQuerySourceDefinition. - Declare safe columns, entity-to-row key mapping, allowed sorts, a default sort and query permission.
- Implement
IAdminQueryScopeProvider<TScope>from authenticated context. Returning null denies execution. - Implement
IAdminQueryHandler<TParameters, TRow, TScope>so mandatory scope applies before optional filters, totals and paging.
Use parameterized SQL or suitable LINQ and a unique key tie-breaker for each ordering. Matrix checks declared bounds and response structure; it cannot prove that an arbitrary handler applies its scope or that joins preserve global key uniqueness. Test fan-out across page boundaries.
Typed query parameters are bounded data, not SQL or expressions. The documented defaults are 100 rows, 10 seconds and 1,000,000 serialized response bytes. Higher configurable bounds are not capacity guarantees. Data-source commands must honor cancellation and their own work limits.
Preserve draft and execution state#
The generated query host separates draft filters from the last successfully applied values. Paging, sort and refresh use applied values while preserving new draft edits. Initialization applies static defaults, dynamic defaults, permitted preferences and permitted navigation in that order. Restoration never supplies server authorization; invalid restoration must not broaden the query silently.
Projected values never become write inputs. Opening an entity form or preparing a record command reloads the authoritative entity and concurrency token. The command reauthorizes and rechecks state at execution. A successful write followed by a failed refresh remains a successful write; retry the read, not the mutation.
Selection commands operate on explicit bounded keys, not every filtered record. Totals describe the complete authorized filtered source before paging. CSV export has separate permission and bounds and performs a fresh read, so it need not match an earlier page after concurrent changes.
Respect renderer and version limits#
The built-in renderer is the default. The optional Blazorise adapter uses Table components over Matrix's query and action model; it does not supply all vendor DataGrid features. Query profiles reject unsupported combinations such as hierarchy or inline editing. Custom pages remain available when a richer interaction is required.
The inspected source includes post-alpha.59 candidates for embedded headings, record-text actions and query composites. Default descending query order is a separate alpha.60 candidate. Check the exact package/kit before using these APIs. Verify dirty navigation, late responses, denied reads, authoritative editing and failed refresh behavior in the application's actual composition.