CoreEx.Database 4.2.0

dotnet add package CoreEx.Database --version 4.2.0
                    
NuGet\Install-Package CoreEx.Database -Version 4.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CoreEx.Database" Version="4.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CoreEx.Database" Version="4.2.0" />
                    
Directory.Packages.props
<PackageReference Include="CoreEx.Database" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CoreEx.Database --version 4.2.0
                    
#r "nuget: CoreEx.Database, 4.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CoreEx.Database@4.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CoreEx.Database&version=4.2.0
                    
Install as a Cake Addin
#tool nuget:?package=CoreEx.Database&version=4.2.0
                    
Install as a Cake Tool

CoreEx.Database

Provides the IDatabase / Database ADO.NET abstraction, DatabaseCommand fluent query builder, DatabaseRecord row 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, DatabaseColumns naming conventions, and DatabaseWildcard configuration.
  • 📝 Fluent command builder: DatabaseCommand accumulates parameters via IDatabaseParameters<T> fluent methods, then executes as non-query, scalar, single-row, first-or-default, collection, or multi-result-set.
  • 📖 DatabaseRecord: Wraps DbDataReader with named and ordinal GetValue<T> accessors that apply DateTimeTransform, null-safety, and RowVersion decoding.
  • 🗂️ Multi-result-set: SelectMultiSetAsync reads multiple result sets in a single round-trip using IMultiSetArgs / MultiSetSingleArgs<T> / MultiSetCollArgs<T> descriptors.
  • 🗃️ Typed mapper contracts: IDatabaseMapper<TSource, TDestination> / IDatabaseMapper<T> define the mapping surface; DatabaseMapper<T> provides an abstract base with MapFromDb / MapToDb override points.
  • 🏷️ Standard column mapping: DatabaseMapper.MapStandardFromDb automatically reads RowVersion → IETag, TenantId, IsDeleted, and change-log columns from DatabaseRecord; MapStandardToDb writes them to parameters.
  • 🦁 Database wildcard: DatabaseWildcard translates CoreEx WildcardResult selections into database LIKE patterns (%, _) with configurable escape character.
  • 📡 DatabaseInvoker tracing: Every command execution is wrapped by DatabaseInvoker (an InvokerBase<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 via IEventPublisher, and marks them as sent — all within a configurable polling hosted service.
  • 🔢 SQL statement abstraction: SqlStatement carries CommandText, CommandType (Text or StoredProcedure), 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.
  • CoreEx.Data - IUnitOfWork, DataResult, QueryArgsConfig; IDatabaseUnitOfWork extends IUnitOfWork.
  • CoreEx.Mapping - Mapper.MapStandardFrom pattern mirrored by DatabaseMapper.MapStandardFromDb for the database layer.
  • CoreEx.Wildcards - WildcardResult produced by Wildcard.Parse() is translated to LIKE patterns by DatabaseWildcard.
  • CoreEx.Invokers - DatabaseInvoker and DatabaseOutboxRelayInvoker extend InvokerBase for OpenTelemetry tracing.
  • CoreEx.Events - IEventPublisher is the outbox relay's publication target; EventData is what the outbox table stores.
  • CoreEx.Database.SqlServer - SQL Server-specific Database implementation, SqlServerDatabaseExtensions, and stored-procedure conventions.
  • CoreEx.Database.Postgres - PostgreSQL-specific Database implementation 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Loading failed