Concept
Architecture overview
The shared typed pipeline under all three access modes, the package layout, and how the dialect layer keeps code portable.
One pipeline, three modes#
Raw SQL (KMQL), Entity and Repository modes are front ends. All of them go through the same execution layer inside DatabaseContext:
Raw SQL (KMQL) Entity (fluent + SaveChanges) Repository (derived from method names)
\ | /
'------------- typed command layer ---------------'
|
markup resolution -> parameter binding -> dispatch
|
database specification (dialect) for the engine in use
|
ADO.NET driver -> database
|
result mapping to typed objects
Because parameter binding, result mapping and query dispatch are written once, the three modes do not have separate code paths. Execution characteristics, such as performance, transactions and (in Enterprise) auditing, do not change with the abstraction you chose.
The dialect layer#
Each supported database has a database specification. It knows how to quote identifiers, write boolean literals, paginate, concatenate strings, format dates, create savepoints and so on. Two features use it:
- KMQL markup resolves tokens such as
{{T:}},{{C:}},{{PAGINATE}}or{{NOW}}by calling the active specification. Where a method already exists on the specification, the resolver reuses it. See the KMQL reference. - Entity and Repository commands generate SQL through the same specification, so their statements are correct for each engine without per-provider code.
Your application code names a provider in exactly one place: the line that connects the context (for example UsePostgreSql(...)).
Positional-parameter drivers#
Some drivers accept only positional ? parameters (for example HCL's Informix driver). Kiwi ORM wraps those connections so @name parameters are rewritten to positional ones, cached per statement text, with each parameter's type taken from its value. Your code is the same as for every other provider.
SQL caching#
Parsed repository method names and the SQL generated for them are cached, so derived queries are analysed once. The cache can be inspected with the repository monitor.
Packages#
The solution is split so you take only what you use:
| Layer | Contents | Edition |
|---|---|---|
| Abstractions | Attributes, context and the auditing hooks (IAuditAdapter, audit contexts) |
Free |
| Core | The pipeline, entity and command layer, the database specifications for all engines, KMQL | Free |
| Cte | Managed CTE builders and per-engine providers | Commercial |
| Source generators | Roslyn generators for entity boilerplate | Free |
| Tooling CLI | Entity generation and migrations (runs in the Kiwi shell) | Free |
| Repository, Repository.DependencyInjection | Repository mode and DI registration | Commercial |
| Auditing adapters | Ready-made audit trail storage in a relational database (all 11 engines) or MongoDB | Commercial |
The assemblies are listed in Packages and assemblies.
Where it is used#
Kiwi ORM Core is the data-access layer under Kiwi Fabric, Kiwi Flow and Kiwi Vault, which use it for their own registries and for the databases they connect to. Kiwi Fabric's registry store can therefore run on any of the engines Kiwi ORM supports.