CoreEx.Database
4.2.0
dotnet add package CoreEx.Database --version 4.2.0
NuGet\Install-Package CoreEx.Database -Version 4.2.0
<PackageReference Include="CoreEx.Database" Version="4.2.0" />
<PackageVersion Include="CoreEx.Database" Version="4.2.0" />
<PackageReference Include="CoreEx.Database" />
paket add CoreEx.Database --version 4.2.0
#r "nuget: CoreEx.Database, 4.2.0"
#:package CoreEx.Database@4.2.0
#addin nuget:?package=CoreEx.Database&version=4.2.0
#tool nuget:?package=CoreEx.Database&version=4.2.0
CoreEx.Database
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.
Overview
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.
Key capabilities
- 🔌 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 factory methods for inline SQL, embedded SQL resources, and stored procedure calls.
Key types
| 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), FromResource(resourceName) (embedded resource), and FromText(text) (runtime-generated SQL). |
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. |
Transaction isolation
The SQL Server and PostgreSQL IUnitOfWork.TransactionAsync overloads accepting provider arguments honor
SqlServerDatabaseArgs.IsolationLevel or PostgresDatabaseArgs.IsolationLevel when creating a root transaction.
Overloads without explicit arguments use the database's configured arguments; the default is ReadCommitted.
The framework owns commit, rollback and disposal, and EfDb enlists its shared connection through
IDatabase.UseTransactionChanged.
Nested calls use savepoints and inherit the parent's isolation level, regardless of their arguments.
They do not upgrade isolation or independently commit the parent. An operation needing a particular isolation
guarantee must verify an existing parent's level. Isolation semantics are provider-specific: PostgreSQL
RepeatableRead provides a stable MVCC snapshot, whereas SQL Server RepeatableRead does not prevent phantoms
and is not a substitute for SQL Server Snapshot.
Read-only callbacks need not enqueue events. At the root boundary, a configured outbox publishes any queued events before commit; nested calls leave publication to their parent.
SQL statement source
Prefer the EF Core / EfDb model APIs for ordinary CRUD and LINQ queries. When application code needs custom
relational SQL, put the static SQL in a named .sql or .pgsql file and embed it in the Infrastructure assembly,
regardless of its length. Load it once with SqlStatement.FromResource<TResource> and execute it through
IDatabase.Statement; keeping SQL in a discoverable resource makes it easier to review and extend without mixing
it into orchestration code.
private static readonly SqlStatement _isReady =
SqlStatement.FromResource<ProductSearchIndex>("ProductSearchIsReady.pgsql");
var ready = await _ef.Database.Statement(_isReady)
.Param("Profile", profile, dbType: DbType.String)
.ScalarAsync<bool>(cancellationToken)
.ConfigureAwait(false);
The Infrastructure project must explicitly embed the files (for example,
<EmbeddedResource Include="Repositories\Sql\*.pgsql" />). Resource lookup matches the end of the fully qualified
resource name, so keep filenames unique within the assembly. Bind values with DatabaseCommand.Param; do not
interpolate user or data values into SQL. Use SqlStatement.FromText only when SQL must genuinely be generated at
runtime, such as when a validated or safely quoted identifier is dynamic; continue to bind data values as
parameters. Keep schema changes in the *.Database project's DbEx migrations, not in runtime query resources.
The Products search implementation is a complete example
(ProductSearchIndex,
search guide).
Namespaces
| 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. |
Related Namespaces
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.
AI Usage Guide
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.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CoreEx (>= 4.2.0)
- CoreEx.Data (>= 4.2.0)
-
net8.0
- CoreEx (>= 4.2.0)
- CoreEx.Data (>= 4.2.0)
-
net9.0
- CoreEx (>= 4.2.0)
- CoreEx.Data (>= 4.2.0)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on CoreEx.Database:
| Package | Downloads |
|---|---|
|
Beef.Database.Core
Business Entity Execution Framework (Beef) Database tool. |
|
|
CoreEx.Database.SqlServer
Core .NET extensions and abstractions for the development of backend services. |
|
|
CoreEx.EntityFrameworkCore
Core .NET extensions and abstractions for the development of backend services. |
|
|
CoreEx.Database.MySql
CoreEx .NET MySQL Database extras. |
|
|
CoreEx.Database.Postgres
Core .NET extensions and abstractions for the development of backend services. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on CoreEx.Database:
| Repository | Stars |
|---|---|
|
Avanade/Beef
The Business Entity Execution Framework (Beef) framework, and the underlying code generation, has been primarily created to support the industrialization of API development.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 4.2.0 | 125 | 10/24/2026 |
| 4.1.0 | 188 | 10/12/2026 |
| 4.0.0 | 196 | 9/21/2026 |
| 4.0.0-preview-5 | 195 | 8/23/2026 |
| 4.0.0-preview-4 | 185 | 8/21/2026 |
| 4.0.0-preview-3 | 287 | 8/4/2026 |
| 4.0.0-preview-2 | 212 | 7/10/2026 |
| 4.0.0-preview-1 | 213 | 6/20/2026 |
| 3.31.0 | 9,231 | 2/1/2025 |
| 3.30.2 | 463 | 12/11/2024 |
| 3.30.1 | 429 | 12/9/2024 |
| 3.30.0 | 2,919 | 11/21/2024 |
| 3.29.0 | 8,371 | 11/19/2024 |
| 3.28.0 | 439 | 11/9/2024 |
| 3.27.3 | 932 | 10/23/2024 |
| 3.27.2 | 455 | 10/17/2024 |
| 3.27.1 | 671 | 10/15/2024 |
| 3.27.0 | 1,428 | 10/11/2024 |
| 3.26.0 | 461 | 10/3/2024 |
| 3.25.6 | 1,133 | 10/2/2024 |