Summary
Add Native AOT support to DbConnectionPlus by replacing runtime-code-generation dependencies with AOT-safe reflection.
Entity and value-tuple materialization will use a reflection-based path under Native AOT while retaining the existing expression-compiled fast path on JIT runtimes.
A source-generator approach was evaluated and benchmarked but rejected: it provided only around 13–16% improvement for SQLite workloads and negligible improvement for SQL Server, while substantially increasing implementation and maintenance complexity.
Scope
- Enable AOT and trimming analysis for all shipping projects.
- Multi-target
net8.0 and net10.0.
- Support
Query<T> for entities, immutable entities, value tuples, and scalars.
- Support entity insert, update, and delete operations.
- Support temporary tables containing scalar and complex values.
- Replace Fasterflect accessors with lazy BCL delegates backed by
MethodInvoker.
- Replace FastMember readers with a generalized
EnumerableReader.
- Remove Fasterflect and FastMember from the dependency graph.
- Preserve equivalent results, conversions, exceptions, and exception messages across the JIT and AOT materializer paths.
API changes
This work targets version 4.0.0 and includes two breaking changes:
- Non-generic query methods return
DataRow instead of dynamic. The AOT-safe access form is row["Id"]; explicit dynamic member access remains available on JIT runtimes.
EntityPropertyMetadata.PropertyGetter and PropertySetter use Func<Object, Object?> and Action<Object, Object?> instead of Fasterflect delegate types.
Materialization will also throw when no result-set columns bind to writable entity properties. This prevents trimming mistakes from silently producing default-valued entities.
Provider support
- SQLite: supported
- MySQL: supported
- PostgreSQL: supported for core paths, with possible plug-in limitations
- SQL Server: supported for the main paths, with provider-specific Entra ID and Always Encrypted caveats
- Oracle: blocked by the current Oracle provider
Generic query methods retain documented trimming/AOT annotations because nested value tuples with more than seven fields cannot be fully described through trimming annotations.
Acceptance criteria
- Entity, immutable-entity, value-tuple, scalar, CRUD, and temporary-table paths work under Native AOT.
- JIT runtimes continue using the expression-compiled materializer path.
- JIT and AOT materializers have behavioral and exception parity.
- Trimming cannot silently return entirely unpopulated entities.
- Fasterflect and FastMember are fully removed.
- A SQLite Native AOT smoke application verifies all supported feature paths and full property population.
- CI publishes and executes the native smoke application and detects unexpected trimming or AOT diagnostics.
- README, XML documentation, CHANGELOG, migration guidance, and provider support documentation are updated for version 4.0.0.
Summary
Add Native AOT support to DbConnectionPlus by replacing runtime-code-generation dependencies with AOT-safe reflection.
Entity and value-tuple materialization will use a reflection-based path under Native AOT while retaining the existing expression-compiled fast path on JIT runtimes.
A source-generator approach was evaluated and benchmarked but rejected: it provided only around 13–16% improvement for SQLite workloads and negligible improvement for SQL Server, while substantially increasing implementation and maintenance complexity.
Scope
net8.0andnet10.0.Query<T>for entities, immutable entities, value tuples, and scalars.MethodInvoker.EnumerableReader.API changes
This work targets version 4.0.0 and includes two breaking changes:
DataRowinstead ofdynamic. The AOT-safe access form isrow["Id"]; explicit dynamic member access remains available on JIT runtimes.EntityPropertyMetadata.PropertyGetterandPropertySetteruseFunc<Object, Object?>andAction<Object, Object?>instead of Fasterflect delegate types.Materialization will also throw when no result-set columns bind to writable entity properties. This prevents trimming mistakes from silently producing default-valued entities.
Provider support
Generic query methods retain documented trimming/AOT annotations because nested value tuples with more than seven fields cannot be fully described through trimming annotations.
Acceptance criteria