Xtraq can auto-bind input parameters (including UDTTs) before a procedure executes. Add a binding once; let the generator hydrate parameters when they are missing.
{
"Api": {
"Requests": {
"AutoBind": [
"@UserId INT",
"@Entries shared.AuditLogEntryTableType READONLY"
],
"AutoBindProcedures": [
"sample.UserCompositeJsonSnapshot",
"sample.WriteAuditLogEntries"
]
}
}
}
AutoBindProcedures filters binding to specific procedures (schema-qualified).AutoBind is informational for you; resolvers live in code.builder.Services.AddHttpContextAccessor();
builder.Services.AddXtraqDbContext(options =>
{
options.ConnectionString = "...";
options.ParameterBindings
.BindScalar<int>("@UserId", async (sp, _) =>
{
var accessor = sp?.GetService<IHttpContextAccessor>();
var sub = accessor?.HttpContext?.User?.FindFirstValue("sub");
return int.TryParse(sub, out var id) ? id : 0;
}, "sample.UserCompositeJsonSnapshot");
});
BindScalar/BindTable(..., params string[] procedures) filter by procedure when needed.null; existing values are respected.Bind*WithInput when you need both ambient data and request data (for example, context TVPs).ConfigureProcedure<TRequest, TInput>) apply bindings before constructing inputs.IReadOnlyList<T>; bindings skip when the request already has a value.Api section when you want the generator to emit <Proc>Request records, table-type request rows, and their mappers. These DTOs feed straight into ConfigureProcedure<TRequest, TInput> and the selector-based ExecuteAsync overloads.ParameterBindingOptions (ResolveValueAsync) before constructing <Proc>Input. If a required parameter stays null, it throws an InvalidOperationException instead of defaulting to zero/empty.IReadOnlyList<T>; bindings fire only when the request leaves the property null. When request projections are enabled, companion TableTypeRequest rows expose DataAnnotations for HTTP validation.StreamResult...Async(request, onRow, ct)); the request is mapped and hydrated before streaming starts, so row handlers see the fully prepared payload.