ServiceStack v10.4 brings OrmLite’s biggest release ever ! We’ve packed it with the features on our wishlist, expanding what you can do with its typed, SQL-friendly approach to .NET data access.
Highlights include:
-
Connection-wide tenant isolation: Define filters and write rules once so typed queries, AutoQuery, updates, deletes and inserts stay within a tenant. Connections can fail closed until the tenant is known, and rules can enforce audit fields and soft deletes.
-
Safer SQL from user input:
Sql.Fmt()parameterizes interpolated values across raw SQL APIs;OrderBySafe()permits customer-selected sorting using approved fields. Fragment validation and identifier escaping are also stronger. -
Schema Diff and migration generation: Compare models with the database, inspect differences in the Admin UI, generate migrations for review, and apply changes in development. SQLite gains
RebuildTable<T>()for changes it cannot make in place. -
Faster large writes:
BulkUpsert()imports and synchronizes thousands of rows; supported drivers also batchInsertAll,UpdateAll,UpsertAllandSaveAllinto fewer round trips. -
Read replicas: Route read-only queries and AutoQuery APIs to replicas, with primary fallback and a read-your-writes window after updates.
-
Automatic retries for temporary database failures: Retry eligible deadlocks, throttling, serialization failures and lost connections, including whole transactions.
-
Vector search: Store embeddings and find similar rows in typed queries, including joins and filters, with vector index and half-precision options where supported.
-
Full-text search: Create database-native text indexes from attributes, search as users type, and rank results by relevance within typed queries.
-
Query performance tools:
db.Explain()exposes query plans; the Admin UI adds a Slowest Queries view with Explain, Analyze and Run Query actions. -
Compiled queries: Generate SQL once for frequently run typed queries, reducing query-building time and allocations, including for tenant-filtered queries.
-
Scalable paging:
SeekAfter()provides stable keyset pagination for large or changing result sets. -
Large-list queries:
SelectByIds,DeleteByIdsand typedContains()queries handle thousands of values automatically within database limits. -
Asynchronous result streaming:
SelectLazyAsync()andColumnLazyAsync()process rows one at a time withawait foreach. -
Typed JSON and array queries: Query nested object properties and list contents directly, including
Any,All,Countand PostgreSQL arrays. -
System-versioned tables: Mark tables to retain row history and query their contents at an earlier time.
-
Typed SQL composition: Combine queries with
Union,UnionAll,IntersectandExcept; name subqueries withWith; traverse hierarchies withWithRecursive; and calculate rankings, running totals and grouped results with window functions. -
Atomic row-returning writes:
UpdateOnlyReturning()andDeleteReturning()return affected rows in the same statement. Upserts now populate database-generated values and row versions on their objects. -
Concurrency and joined updates:
ForUpdate()locks selected rows, including skip-locked work queues;UpdateFrom()updates rows using values and filters from joined tables. -
Richer model-defined schemas: Attributes now cover filtered and covering indexes, generated columns, enum checks and database comments.
-
Runtime table reads: Untyped APIs can select, fetch by ID and count rows when a table is known only by its
Type, with async equivalents.
AI.Chat
AI.Chat also gets a major update, Highlights:
-
Decision Studio in AI.Chat: Build reusable typed decision recipes, compare saved examples, manage a recipe library, and import or share recipes.
-
Decisions API: Ask AI yes/no, choice and scale questions from C# or HTTP and receive validated answers with probabilities, usage and cost.
-
Authenticated user API keys: User API keys can call eligible authenticated APIs; built-in API key management also uses request-scoped connections for tenant filtering.
-
AI.Chat workspace and Git panels: Browse files, preview content, review diffs, stage changes, commit, inspect history, stash and sync from the interface.
-
AI.Chat repository projects: Clone repositories into new projects, reorder projects and archive or restore them.
-
ChatGPT subscription connection: Connect a personal ChatGPT account for eligible AI.Chat text requests.
-
Recoverable Gemini imports: Save portable folder and website import settings, synchronize changed sources, and resume interrupted uploads.
-
Static project publishing: Export an AI.Chat project to a folder served by your own static server, with configurable destinations.
-
Faster AI.Chat loading and smaller transfers: Features load when opened, shared modules preload, responses use compression and assets support cache revalidation.
-
AI.Chat usability updates: Searchable model pickers, improved skill navigation, refreshed provider metadata and smaller interface refinements.
Read the full v10.4 release notes for examples, demos, benchmarks, and upgrade details.

