Net4x.DapperLibrary.Base
1.9.9.7
See the version list below for details.
dotnet add package Net4x.DapperLibrary.Base --version 1.9.9.7
NuGet\Install-Package Net4x.DapperLibrary.Base -Version 1.9.9.7
<PackageReference Include="Net4x.DapperLibrary.Base" Version="1.9.9.7" />
<PackageVersion Include="Net4x.DapperLibrary.Base" Version="1.9.9.7" />
<PackageReference Include="Net4x.DapperLibrary.Base" />
paket add Net4x.DapperLibrary.Base --version 1.9.9.7
#r "nuget: Net4x.DapperLibrary.Base, 1.9.9.7"
#:package Net4x.DapperLibrary.Base@1.9.9.7
#addin nuget:?package=Net4x.DapperLibrary.Base&version=1.9.9.7
#tool nuget:?package=Net4x.DapperLibrary.Base&version=1.9.9.7
DapperLibrary
DapperLibrary is a lightweight data-access library that builds on ADO.NET and Dapper to provide a consistent, engine-agnostic API for querying and manipulating relational databases. The library centers on the DapperContext class and the IDapperContext interface which encapsulate connection creation, command execution, parameter handling and schema helpers.
Overview
- Core types:
DapperContext(concrete) andIDapperContext(interface). Create an instance ofDapperContext(or use a provider-specific derived context) and use it via theIDapperContextsurface to execute commands and queries. - The library supports multiple database engines (SQL Server, Oracle, MySQL, PostgreSQL, SQLite, and more) through provider factories and engine-specific context helpers.
DapperContextmanages connection lifetime automatically and exposes a rich set of synchronous and asynchronous operations.
Multi-targeting and framework support
This repository is designed to support a broad range of .NET frameworks to make the library usable in legacy and modern applications. The source contains conditional compilation directives and multi-targeted build configurations so different assemblies are produced for different target frameworks. Supported frameworks include (but are not limited to):
- .NET Framework 3.5
- .NET Framework 4.0
- .NET Framework 4.5 / 4.6.1 / 4.7.2 / 4.8
- .NET Standard 2.0 / 2.1
- .NET 6, .NET 8, .NET 10 (modern .NET)
Notes about multi-targeting:
- Conditional compilation (#if NETSTANDARD, #if NET8_0_OR_GREATER, etc.) is used to vary implementations that depend on runtime APIs (for example JSON serialization, configuration APIs, or host builder integration).
- NuGet packages produced from this source include framework-specific assemblies. Consumers should reference the package from the target framework matching their application to get the appropriate implementation.
- Where APIs differ between frameworks (e.g.,
ConfigurationManager,IHostApplicationBuilderavailability, orSystem.Text.JsonvsNewtonsoft.Json), the library exposes equivalent surface behavior while using the most appropriate underlying runtime facility.
Key concepts
IDapperContext/DapperContext- Use a
DapperContextinstance to obtain database access. The instance is responsible for creating and trackingDbConnectioninstances and for closing them when appropriate. IDapperContextexposes anOperations/Schemasurface for segregated responsibilities (query/set operations vs schema inspection).- Provider-specific convenience helpers exist (e.g.
SqlDapperContext,MySqlDapperContext) to simplify engine-specific configuration and lifetime semantics.
- Use a
Multiple connection types and mixing engines
- You can have different
DapperContextobjects for different engines and mix them in the same application. - Typical usage patterns include
SqlDapperContext.Use(),SqlDapperContext.UseOnce(),MySqlDapperContext.Use(),MySqlDapperContext.UseOnce()to simplify scoped or one-off usage.
- You can have different
In-memory & mocked database support
- The library includes helpers to use an in-memory engine (SQLite) for tests.
- A mocked SQL Server implementation (lite) and Dapper-based mocks are available for unit tests.
- The library integrates with containerized or mocked DB runtimes via test containers (TestContainers.* NuGet packages) when needed.
Managing connection strings
DapperContext provides several APIs and properties to control which connection string is used for operations and how a connection string is resolved:
ConnectionStringToRead(string)- The active connection name used by the context when creating new connections. Many convenience methods use this value as the default connection name.
- Set this property to point the context at a different connection (by name) at runtime. Example:
context.ConnectionStringToRead = "MyOtherConnection".
ConnectionStringSettingsandAlternativeConnectionStringConnectionStringSettingscan hold the currently active connection settings. When a configuredConnectionStringSettingsis present the context will prefer its connection string.AlternativeConnectionStringserves as a fallback value if no configuration provider or settings supply a concrete connection string.
ConnectionStrings(IConnectionStrings)- The context exposes a
ConnectionStringscollection that is initialized from the owningDapperContextFactory/ configuration manager. Usecontext.ConnectionStrings[...]or theConnectionStrings.Currenthelpers to inspect available named connections.
- The context exposes a
GetConnectionString(string connectionStringName)- Resolve the actual connection string text by name. This method merges configured values, factory defaults and
AlternativeConnectionString, and raises aConnectionStringEventArgsthat can be patched byDapperContextFactoryinternals. - Use this method when you need the raw connection string value instead of the connection-name.
- Resolve the actual connection string text by name. This method merges configured values, factory defaults and
Custom connections via indexer
context[connectionStringName]returns anICustomConnectionbound to that name (useful for per-connection shortcuts and schema helpers).
Notes and best practices
- Set
ConnectionStringToReadonce during initialization when a context is used for a single logical database. Change it dynamically only when you understand the effect on pooled/allocated connections. - Prefer the explicit
WithConnection(...)overload when you must perform an operation against a different database for a single call; that avoids race conditions around concurrent operations and reader-associated connections. - When combining multiple engines or databases, keep a separate
DapperContextper engine/connection string to keep behavior predictable and to avoid mixing provider factories.
Schema helpers and caching
DapperLibrary exposes a typed, convenient schema inspection surface through IDapperContext.Schema (and the concrete DapperContext.Schema property). The ISchema surface aggregates small helper types that make reading table metadata easy and concise.
- Schema helper properties available on
ISchema(examples):ColumnNames� indexerColumnNames[tableName]returns an array of column names for the table.IdentityColumnIndex� indexerIdentityColumnIndex[tableName]returns the ordinal of the identity/autoincrement column.IdentityColumn� indexerIdentityColumn[tableName]returns the identity column name (if any).PrimaryKeyColumnNames� indexerPrimaryKeyColumnNames[tableName]returns the primary key column names.SchemaTableTypes� indexerSchemaTableTypes[tableName]returns an array of richSchemaTabledescriptors.UniqueKeyColumnNames� indexerUniqueKeyColumnNames[tableName]returns unique columns.AllowDbNull,ColumnOrdinal,ColumnSize,ColumnType,NumericPrecision,NumericScale,ProviderType� each type exposes indexers with either a(tableName, columnName)or(tableName, index)overload for convenience.
Usage examples:
- Read column names:
var names = context.Schema.ColumnNames["Orders"]; - Inspect column type:
var dt = context.Schema.ColumnType["Orders", "OrderDate"]; - Read identity ordinal:
var idx = context.Schema.IdentityColumnIndex["Orders"];
With-connection overloads
- The schema helper types have constructors that accept a
connectionStringName. When a helper is initialized with a connection string the indexers call*WithConnectionvariants internally (for exampleGetSchemaTableWithConnection) so you can query schema on a different named connection viacontext.SchemaWithConnection(name)-style factories (the library exposes ways to build schema helpers bound to a named connection).
Caching behavior
- Reading schema metadata is relatively expensive; the library caches schema reads internally to avoid repeating database queries.
- Under the hood the schema helpers call
GetSchemaTableWithConnection(...), which usesCacheUtility.Instance.GetValueFromCachewith a cache key typically built from the resolved connection string and the table name. Common cache keys follow the pattern:${connectionString}_${tableName}_SchemaTable,${connectionString}_${tableName}_ColumnNames, etc. - Cache entries include the computed
SchemaTable[], column names arrays and other derived values. The cache reduces round-trips and speeds up repeated metadata inspection.
Cache invalidation
- When the library performs DDL-like operations (create/alter/drop table), or an operation that changes the database layout, it will attempt to clean related cache entries (see methods such as
CleanCacheForTableand the internal paths that call it). - If you perform schema changes outside of
DapperContext(e.g., manually via another process), you may need to evict or refresh the cache programmatically. The internalCacheUtilityAPI is used for caching; extend or call into that helper to control cache lifetime if required.
Best practices
- Use schema helpers for read-only metadata lookup and rely on the cache for performance.
- When doing programmatic schema changes within your application, perform the change through
DapperContextoperations so the library can invalidate cached metadata. - For cross-connection schema inspection, prefer the helper constructors that accept a connection string name so cached results are kept per resolved connection string.
Automatic connection lifetime management
DapperContextopensDbConnectioninstances as needed and keeps track of them in an internalBehaviorcontainer.If a
DbDataReaderis opened on a connection, and you execute another statement on the sameDapperContext, a new connection will be opened automatically to avoid interfering with the reader.Disposing the
DapperContextwill close all owned connections. If aDapperContextis not explicitly disposed, its finalizer will still attempt to close open connections when the GC collects the object.You can explicitly close the connection associated with a specific reader using
DapperContext.CloseConnectionAssociatedWithDataReader(DbDataReader reader).The property
DapperContext.CloseConnectioncontrols detailed closing behavior; it maps to underlyingCommandBehaviorandBehavior.KeepOpensemantics. The library supports the three typical behaviours:AsSoonAsPossible� connections closed immediately after operations completeWhenDataReaderCloses� keep connection open until the reader is disposedAtDispose� keep connections open until theDapperContextis disposed
Inspect the
BehaviorandCloseConnectionusage inDapperContextand related code to see how the container selects, reuses, and disposes connections.
Automatic parameter management
- The library abstracts parameters via indexed placeholders inside SQL text. Placeholders use the form
{i}or{i:out}inside a statement.- Example:
SELECT {0:out}, Field1, {1}+' Test' FROM SqlTestTable WHERE KeyField = {2} - During preparation this becomes
SELECT @Par0, Field1, @Par1+' Test' FROM SqlTestTable WHERE KeyField = @Par2(parameter names like@Par0,@Par1, etc.).
- Example:
- Parameter translation and preparation is centralized in the
ParameterModelclass and related helpers such asParameterModel.DefaultPrepareCommandParameters(seeParameterModel.PrepareDynamicParametersandPrepareCommandParametersfor details).- The model supports output parameters (with
:outmarker), named parameters, and dynamic parameter objects (DapperDynamicParameters). - The parameter system also handles copying back output values to the original parameter array after execution.
- The model supports output parameters (with
Synchronous and asynchronous methods
DapperLibrary exposes both synchronous and asynchronous versions of most operations so it can be used in synchronous legacy applications as well as modern async/await code paths. Common patterns and guidance:
- For each high-level operation there is typically a synchronous variant and an
Asyncsuffix variant. Examples:- Synchronous:
GetDataTable,GetDataReader,SetData,GetScalar<T>,SaveDataTable,Save<T>etc. - Asynchronous:
GetDataTableAsync,GetDataReaderAsync,SetDataAsync,GetScalarAsync<T>,SaveDataTableAsync,SaveAsync<T>etc.
- Synchronous:
- Use the asynchronous variants in I/O-bound, latency-sensitive applications (ASP.NET Core, background services) to avoid blocking thread-pool threads. Use synchronous APIs in legacy code paths or where async propagation is impractical.
- Internals: async implementations rely on
DbCommand/DbDataReaderasync methods where supported by the provider and are guarded by conditional compilation for older frameworks that do not support Task-based ADO.NET async APIs. - When mixing sync and async calls on the same
DapperContext, be mindful of connection reentrancy: opening a long-livedDbDataReadervia a sync call may cause subsequent operations to open separate connections; prefer async patterns end-to-end when using async readers.
Offered functionality (high level)
Basic ADO.NET style operations
GetScalar<T>� executes a command and returns a scalar value (ExecuteScalarbehavior)GetDataReader� open a reader (ExecuteReaderbehavior)SetData� execute non-query statements (ExecuteNonQuerybehavior)GetDataTable/GetDataSet� build aDataTable/DataSetfrom reader resultsSaveDataTable� use aDbDataAdapterto persist aDataTableto the database (adapter commands created from table schema)
Dapper-based query operations
Query<T>� maps rows to entities via DapperQuery<T>QuerySingle<T>,QueryFirstOrDefault<T>� single-row mappingQueryMultiple� use DapperQueryMultipleto read multiple result sets
Entity-oriented persistence helpers
Save<T>andSaveEnumerable<T>to persist entities (single and enumerable)Delete<T>andDeleteEnumerable<T>to remove entities- Hooks for customizing entity mapping (see attributes below)
Schema helpers
Schemahelpers expose metadata like column names, column sizes, types, primary keys and identity column info.- Use
IDapperContext.Schemato inspect table metadata in a provider-agnostic manner.
Entity mapping attributes
To customize entity-to-table mapping the library supports attributes on entity classes and properties. Typical attributes include:
TableNameAttribute� map a CLR type to a specific database tableColumnNameAttribute� map a CLR property to a specific column namePrimaryKeyAttribute(int position)� define primary key properties and their orderTimestampAttribute� mark a property as a timestamp/rowversion
These attributes are used by the library�s
DatabaseModelandParameterModelto generate correct SQL and mapping behavior.
Test support and mocking
DapperLibraryships helpers for in-memory testing (SQLite), mocked SQL Server runtimes and integration with containerized test DBs (TestContainers).* packages.- There are also specialized helpers for creating an in-memory Northwind dataset used by the test suite (
NorthwindHelper).
Where to look in the codebase
- Main entry points:
DapperContext,IDapperContext,IDapperOperationsandParameterModel. - Schema helpers:
IDapperContext.Schemaand implementations underDbContexts\Schema. - Operations: check
Operationsimplementations andDapperContext.Operations.csfor the facade delegations. - Low-level plumbing:
LowLevelDapperContextfor direct ADO.Net interactions andDapperContextQueryUsingParametersfor Dapper parameter handling.
NuGet-style description (summary)
DapperLibrary provides an engine-agnostic, Dapper-enhanced data access surface centered on DapperContext/IDapperContext. It simplifies parameter handling, connection lifetime management and schema inspection while exposing common ADO.NET and Dapper operations. Ideal for apps that need a thin abstraction over multiple relational databases with strong testability support (in-memory and mocks).
This README is a placeholder. Refer to the project sources and XML documentation inside the code for detailed API usage and advanced configuration examples.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net35 is compatible. net40 is compatible. net403 was computed. net45 is compatible. net451 was computed. net452 was computed. net46 was computed. net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 3.5
- Dapper.StrongName (>= 1.38.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Extensions.Configuration.Abstractions (>= 2.5.0.5)
- Net4x.Extensions.Logging.Library (>= 2.5.0.5)
- Net4x.Runtime.Caching (>= 1.3.0)
- Newtonsoft.Json (>= 13.0.4)
-
.NETFramework 4.0
- Dapper.StrongName (>= 1.50.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Extensions.Configuration.Abstractions (>= 2.5.0.5)
- Net4x.Extensions.Logging.Library (>= 2.5.0.5)
- Net4x.Runtime.Caching (>= 1.3.0)
- Newtonsoft.Json (>= 13.0.4)
-
.NETFramework 4.5
- Dapper.StrongName (>= 1.50.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Extensions.Configuration.Library (>= 2.5.0.5)
- Net4x.Extensions.Logging.Library (>= 2.5.0.5)
- Net4x.Runtime.Caching (>= 1.3.0)
- Newtonsoft.Json (>= 13.0.4)
-
.NETFramework 4.6.1
- Dapper.StrongName (>= 1.50.0)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.Configuration.Json (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Runtime.Caching (>= 1.3.0)
- Newtonsoft.Json (>= 13.0.4)
- System.Text.Json (>= 10.0.0)
-
.NETStandard 2.0
- Dapper.StrongName (>= 2.0.123)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.Configuration.Json (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Runtime.Caching (>= 1.3.0)
- System.Configuration.ConfigurationManager (>= 9.0.0)
- System.Data.DataSetExtensions (>= 4.5.0)
- System.Reflection.Emit (>= 4.7.0)
- System.Text.Json (>= 10.0.0)
-
.NETStandard 2.1
- Dapper.StrongName (>= 2.0.123)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.Configuration.Json (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Net4x.AsyncBridge (>= 1.5.0.9)
- Net4x.AsyncBridgeExtensions (>= 1.0.0.1)
- Net4x.BaseTypes (>= 1.3.1.15)
- Net4x.Runtime.Caching (>= 1.3.0)
- System.Configuration.ConfigurationManager (>= 9.0.0)
- System.Reflection.Emit (>= 4.7.0)
- System.Text.Json (>= 10.0.0)
NuGet packages (27)
Showing the top 5 NuGet packages that depend on Net4x.DapperLibrary.Base:
| Package | Downloads |
|---|---|
|
Net4x.DapperLibrary.SqlServer
Package Description |
|
|
Net4x.SpreadsheetLibrary.Base
Package Description |
|
|
Net4x.DapperLibrary.SQLite
Package Description |
|
|
Net4x.DapperLibrary.MockSqlServer
Package Description |
|
|
Net4x.DapperLibrary.StatementBuilder
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.9.9.8 | 934 | 2/2/2026 |
| 1.9.9.7 | 1,056 | 1/13/2026 |
| 1.9.9.6 | 960 | 1/6/2026 |
| 1.9.9.5 | 964 | 1/6/2026 |
| 1.9.9.4 | 958 | 1/6/2026 |
| 1.9.9.3 | 1,033 | 1/5/2026 |
| 1.9.9.2 | 932 | 12/30/2025 |
| 1.9.9.1 | 973 | 12/30/2025 |
| 1.9.9 | 1,038 | 12/22/2025 |
| 1.6.0.12 | 939 | 12/12/2025 |
| 1.6.0.11 | 932 | 12/12/2025 |
| 1.6.0.10 | 1,170 | 12/9/2025 |
| 1.6.0.9 | 884 | 12/4/2025 |
| 1.6.0.8 | 868 | 12/4/2025 |
| 1.6.0.7 | 945 | 11/30/2025 |
| 1.6.0.6 | 944 | 11/27/2025 |
| 1.6.0.5 | 902 | 11/22/2025 |
| 1.6.0.4 | 835 | 11/16/2025 |
| 1.6.0.3 | 811 | 11/15/2025 |
| 1.6.0.2 | 991 | 11/14/2025 |