Provides the
IDatabase/DatabaseADO.NET abstraction,DatabaseCommandfluent query builder,DatabaseRecordrow reader, multi-result-set support, convention-based column mapping, database wildcard translation, typed mapper contracts, and the transactional outbox relay infrastructure for publishing events from a relational database.
CoreEx.Database wraps ADO.NET (DbConnection, DbCommand, DbDataReader) with a fluent, OpenTelemetry-instrumented API that integrates tightly with CoreEx entity contracts. Every operation flows through DatabaseCommand, which accumulates a DatabaseParameterCollection, opens the connection on demand, and executes via DatabaseInvoker to emit spans and structured log entries.
The package follows an explicit-mapping philosophy: IDatabaseMapper<TSource, TDestination> implementations hand-write the column-to-property assignments (calling DatabaseRecord.GetValue<T>(columnName) and DatabaseParameterCollection.AddParameter). The DatabaseMapper static utility handles the cross-cutting columns (RowVersion → IETag, TenantId, IsDeleted, CreatedBy/CreatedOn/UpdatedBy/UpdatedOn) so individual mappers only write their entity-specific columns.
The outbox sub-namespace implements the Transactional Outbox pattern: events are written to an outbox table within the same database transaction as the business mutation; the relay hosted service polls the table and publishes to the configured IEventPublisher.
- 🔌 IDatabase abstraction:
IDatabase/Database<TConn>manage connection lifetime, transaction enlistment,DateTimeTransform,DateTimeOffsetTransform,DatabaseColumnsnaming conventions, andDatabaseWildcardconfiguration. - 📝 Fluent command builder:
DatabaseCommandaccumulates parameters viaIDatabaseParameters<T>fluent methods, then executes as non-query, scalar, single-row, first-or-default, collection, or multi-result-set. - 📖 DatabaseRecord: Wraps
DbDataReaderwith named and ordinalGetValue<T>accessors that applyDateTimeTransform, null-safety, andRowVersiondecoding. - 🗂️ Multi-result-set:
SelectMultiSetAsyncreads multiple result sets in a single round-trip usingIMultiSetArgs/MultiSetSingleArgs<T>/MultiSetCollArgs<T>descriptors. - 🗃️ Typed mapper contracts:
IDatabaseMapper<TSource, TDestination>/IDatabaseMapper<T>define the mapping surface;DatabaseMapper<T>provides an abstract base withMapFromDb/MapToDboverride points. - 🏷️ Standard column mapping:
DatabaseMapper.MapStandardFromDbautomatically readsRowVersion→IETag,TenantId,IsDeleted, and change-log columns fromDatabaseRecord;MapStandardToDbwrites them to parameters. - 🦁 Database wildcard:
DatabaseWildcardtranslates CoreExWildcardResultselections into databaseLIKEpatterns (%,_) with configurable escape character. - 📡 DatabaseInvoker tracing: Every command execution is wrapped by
DatabaseInvoker(anInvokerBase<IDatabase>) emitting OpenTelemetry spans tagged with command text, operation result, and error details. - 📤 Transactional outbox relay:
DatabaseOutboxRelayBase<TDatabase, TSelf>polls an outbox table, deserializes events, publishes them viaIEventPublisher, and marks them as sent — all within a configurable polling hosted service. - 🔢 SQL statement abstraction:
SqlStatementcarriesCommandText,CommandType(TextorStoredProcedure), and convenience factory methods for inline SQL and stored procedure calls.
| Type | Description |
|---|---|
IDatabase |
Core database interface: GetConnectionAsync, CreateCommand(SqlStatement), CurrentTransaction, BeginTransactionAsync, DateTimeTransform, NamedColumns, Wildcard. |
Database |
Abstract base IDatabase implementation for a specific DbConnection type; manages connection pooling, transaction stack, and DatabaseInvoker invocation. |
DatabaseCommand |
Fluent command builder: Parameters (DatabaseParameterCollection), NonQueryAsync, ScalarAsync, SelectSingleAsync, SelectFirstOrDefaultAsync, SelectQueryAsync, SelectMultiSetAsync. |
DatabaseRecord |
Wraps DbDataReader: GetValue<T>(string/int), GetRowVersion(), ordinal caching, and null-safe typed reads with DateTimeTransform applied. |
DatabaseParameterCollection |
DbParameterCollection wrapper with AddParameter<T>, AddRowVersionParameter, AddReturnValueParameter, and batch helpers; fluent via IDatabaseParameters<T>. |
SqlStatement |
Carries CommandText and CommandType; factory methods StoredProcedure(name), FromText(text) (in-line) and FromResource(resourceName) (embedded resource). |
DatabaseArgs |
Per-operation options: transaction IsolationLevel, Refresh, and TransformException behavior overrides. |
DatabaseInvoker |
InvokerBase<IDatabase> emitting OpenTelemetry spans and structured log entries for every command execution. |
IDatabaseMapper<T> |
Bidirectional mapper interface: MapFromDb(DatabaseRecord, OperationType) → T; MapToDb(T, DatabaseParameterCollection, OperationType). |
DatabaseMapper<T> |
Abstract base for IDatabaseMapper<T>; override OnMapFromDb and OnMapToDb; call MapStandardFromDb / MapStandardToDb for convention columns. |
DatabaseMapper |
Static utility: MapStandardFromDb reads RowVersion/TenantId/IsDeleted/change-log columns; MapStandardToDb writes them as parameters. |
DatabaseWildcard |
Translates WildcardResult to a database LIKE pattern with configurable wildcard (%) and single-char (_) tokens and escape character. |
DatabaseColumns |
Convention column name constants and overrides: RowVersionName, TenantIdName, IsDeletedName, and change-log column names. |
MultiSetSingleArgs<T> |
IMultiSetArgs for a single-row result set within SelectMultiSetAsync; invokes mapper and stores the mapped value. |
MultiSetCollArgs<T> |
IMultiSetArgs for a collection result set within SelectMultiSetAsync; invokes mapper for each row and stores the collection. |
IDatabaseUnitOfWork |
Extends IUnitOfWork with Database property for direct database access within a unit-of-work. |
DatabaseOutboxRelayBase<TDatabase, TSelf> |
Abstract base for the outbox relay: polls an outbox table, publishes events via IEventPublisher, marks entries as sent, with configurable batch size and SQL statements. |
DatabaseOutboxRelayHostedServiceBase |
TimerHostedServiceBase subclass that drives IDatabaseOutboxRelay.RelayAsync on a timer. |
DatabaseOutboxPublisherBase |
Abstract base IEventPublisher that writes EventData entries to the outbox table within the current database transaction. |
| Namespace | Description |
|---|---|
Abstractions |
DatabaseArgs, DatabaseArgsBase, DatabaseInvoker, and IDatabaseParameters interface. |
Extended |
DatabaseColumns, DatabaseWildcard, IMultiSetArgs, MultiSetSingleArgs<T>, MultiSetCollArgs<T>. |
Mapping |
IDatabaseMapper<T>, DatabaseMapper<T> abstract base, and DatabaseMapper static utility. |
Outbox |
Transactional outbox relay: DatabaseOutboxRelayBase, DatabaseOutboxRelayHostedServiceBase, DatabaseOutboxPublisherBase, DatabaseOutboxRelayArgs. |
CoreEx.Data-IUnitOfWork,DataResult,QueryArgsConfig;IDatabaseUnitOfWorkextendsIUnitOfWork.CoreEx.Mapping-Mapper.MapStandardFrompattern mirrored byDatabaseMapper.MapStandardFromDbfor the database layer.CoreEx.Wildcards-WildcardResultproduced byWildcard.Parse()is translated to LIKE patterns byDatabaseWildcard.CoreEx.Invokers-DatabaseInvokerandDatabaseOutboxRelayInvokerextendInvokerBasefor OpenTelemetry tracing.CoreEx.Events-IEventPublisheris the outbox relay's publication target;EventDatais what the outbox table stores.CoreEx.Database.SqlServer- SQL Server-specificDatabaseimplementation,SqlServerDatabaseExtensions, and stored-procedure conventions.CoreEx.Database.Postgres- PostgreSQL-specificDatabaseimplementation and Npgsql extensions.
An AGENTS.md file is included with this package. AI coding assistants (GitHub Copilot, Claude, Cursor, etc.) that support workspace-injected package documentation will automatically surface concise usage guidance, code examples, and Do Not rules for this package without requiring a local CoreEx checkout.