cs0t.AspNetCore.Identity.Dapper.Oracle11g 1.0.7

dotnet add package cs0t.AspNetCore.Identity.Dapper.Oracle11g --version 1.0.7
                    
NuGet\Install-Package cs0t.AspNetCore.Identity.Dapper.Oracle11g -Version 1.0.7
                    
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="cs0t.AspNetCore.Identity.Dapper.Oracle11g" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="cs0t.AspNetCore.Identity.Dapper.Oracle11g" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="cs0t.AspNetCore.Identity.Dapper.Oracle11g" />
                    
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 cs0t.AspNetCore.Identity.Dapper.Oracle11g --version 1.0.7
                    
#r "nuget: cs0t.AspNetCore.Identity.Dapper.Oracle11g, 1.0.7"
                    
#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 cs0t.AspNetCore.Identity.Dapper.Oracle11g@1.0.7
                    
#: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=cs0t.AspNetCore.Identity.Dapper.Oracle11g&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=cs0t.AspNetCore.Identity.Dapper.Oracle11g&version=1.0.7
                    
Install as a Cake Tool

cs0t.AspNetCore.Identity.Dapper.Oracle11g

Originally forked from : https://github.com/simonfaltum/AspNetCore.Identity.Dapper

A Dapper-backed implementation of ASP.NET Core Identity user and role stores for Oracle 11g, specifically Oracle Database 11g 11.2.0.3.0.

The package uses ApplicationUser : IdentityUser<long> and ApplicationRole : IdentityRole<long>, supports the standard Identity manager APIs, and targets netstandard2.1 and net8.0.

Features

  • Dapper-based IUserStore and IRoleStore implementations
  • Users, roles, claims, user-role links, external logins, and authentication tokens
  • Oracle sequences and RETURNING ... INTO for generated long IDs
  • Optimistic concurrency through Identity concurrency stamps
  • Lazy relationship loading with in-memory synchronization
  • Atomic aggregate creation and updates
  • Configurable schema, table names, and sequence names
  • Oracle 11g-compatible DML and managed Oracle connections
  • Custom Dapper handlers for bool, DateTimeOffset, and Guid

Persistence and in-memory synchronization

Core lookups such as FindByIdAsync, FindByNameAsync, and FindByEmailAsync load only the user or role row. Relationship collections remain null until an Identity operation needs them.

Collection state contract

For ApplicationUser.Claims, Roles, Logins, and Tokens, and ApplicationRole.Claims:

Collection state Meaning during CreateAsync or UpdateAsync
null Not loaded or changed. The corresponding table is not modified.
Empty list Authoritative empty state. Existing relationships are deleted.
Populated list Authoritative state. Existing rows are deleted and the list is reinserted.

This null boundary protects relationships when a detached or partially populated object is updated. Do not initialize an unused collection on a detached object unless replacing that relationship set is intentional.

Point operations

Identity operations such as adding a claim, assigning a role, adding a login, or setting a token use write-through synchronization:

  1. The relevant collection is loaded once if it is currently null.
  2. Logical duplicates are rejected or skipped in memory.
  3. A targeted INSERT, UPDATE, MERGE, or DELETE is executed immediately.
  4. The in-memory collection is changed only after the SQL operation succeeds.

Further reads of that collection on the same object use memory. Unrelated collections remain unloaded.

ApplicationUser.Roles uses ApplicationUserRole, which adds RoleName and NormalizedRoleName to the Identity user-role link. This allows role-name reads and membership checks from the loaded collection.

Aggregate operations

CreateAsync and UpdateAsync persist the core row and every non-null relationship collection in one transaction. Child foreign keys are assigned from the aggregate root ID. Duplicate logical relationships in detached aggregates are rejected before SQL is executed.

Updates use an atomic optimistic-concurrency predicate: the store creates a new concurrency stamp, while the provider compares the database stamp with the original stamp in the UPDATE statement. A conflict rolls back the transaction and restores the original in-memory stamp.

Deletes expect the Oracle schema to cascade from users and roles to their dependent relationship rows.

Oracle type handling

AddOracle11GConnectionFactory registers the handlers globally with Dapper:

  • OracleBoolHandler maps nullable and non-nullable bool values to numeric 0/1 values suitable for an Oracle numeric column.
  • OracleDateTimeOffsetHandler maps DateTimeOffset to Oracle TIMESTAMP WITH TIME ZONE and writes values in UTC.
  • OracleGuidHandler maps Guid to 16-byte binary data and converts between .NET and Oracle byte ordering. Use an Oracle RAW(16) column for values handled this way.

The default connection factory also enables bind-by-name and configures the managed Oracle client to permit Oracle 11g authentication:

OracleConfiguration.SqlNetAllowedLogonVersionClient =
    OracleAllowedLogonVersionClient.Version11;

Installation

Install the package when it is available from your configured NuGet source:

dotnet add package cs0t.AspNetCore.Identity.Dapper.Oracle11g

For source development, add a project reference instead:

dotnet add reference path\to\cs0t.AspNetCore.Identity.Dapper.Oracle11g.csproj

ASP.NET Core Identity setup

Registration is split into two IdentityBuilder extensions:

  • AddDapperStores() registers UserStore and RoleStore with ASP.NET Core Identity.
  • AddOracle11GConnectionFactory(options => ...) configures Oracle 11g, registers the Dapper type handlers, and registers the scoped IDatabaseConnectionFactory.

Call both methods after AddIdentityCore<ApplicationUser>() and AddRoles<ApplicationRole>(). AddDapperStores supports exactly the provided ApplicationUser and ApplicationRole types; custom Identity entity types are not supported.

using cs0t.AspNetCore.Identity.Dapper.Oracle11g;
using cs0t.AspNetCore.Identity.Dapper.Oracle11g.Models;
using Microsoft.AspNetCore.Identity;

builder.Services
    .AddIdentityCore<ApplicationUser>(options =>
    {
        options.User.RequireUniqueEmail = true;
        options.Password.RequiredLength = 8;
    })
    .AddRoles<ApplicationRole>()
    .AddDapperStores()
    .AddOracle11GConnectionFactory(options =>
    {
        options.ConnectionString = builder.Configuration
            .GetConnectionString("IdentityDatabase")!;
        options.DbSchema = "IDENTITY";
    });

The same registration works with AddIdentity<ApplicationUser, ApplicationRole>():

using cs0t.AspNetCore.Identity.Dapper.Oracle11g;
using cs0t.AspNetCore.Identity.Dapper.Oracle11g.Models;
using Microsoft.AspNetCore.Identity;

builder.Services
    .AddIdentity<ApplicationUser, ApplicationRole>(options =>
    {
        options.User.RequireUniqueEmail = true;
        options.Password.RequiredLength = 8;
    })
    .AddDapperStores()
    .AddOracle11GConnectionFactory(options =>
    {
        options.ConnectionString = builder.Configuration
            .GetConnectionString("IdentityDatabase")!;
        options.DbSchema = "IDENTITY";
    });

The separation is intentional: store registration is independent of connection creation. Applications using the package's default Oracle connection factory should call both extensions. Advanced applications may call AddDapperStores() and register their own IDatabaseConnectionFactory; in that case they are also responsible for equivalent Oracle client and Dapper type-handler configuration.

Database configuration

The application must reference or otherwise provide Oracle Managed Data Access. AddOracle11GConnectionFactory globally configures that provider for Oracle 11g authentication (OracleConfiguration.SqlNetAllowedLogonVersionClient = OracleAllowedLogonVersionClient.Version11) and enables bind-by-name. It also globally registers Dapper handlers for bool, nullable bool, DateTimeOffset, nullable DateTimeOffset, Guid, and nullable Guid.

It registers a scoped IDatabaseConnectionFactory; the factory creates and asynchronously opens managed OracleConnection instances.

The application must provide an existing Oracle schema with the required Identity tables, sequences, foreign keys, indexes, and constraints. This package does not provide migrations. The default object names are:

Purpose Default name
Users ASPNET_USERS
Roles ASPNET_ROLES
User roles ASPNET_USER_ROLES
User claims ASPNET_USER_CLAIMS
Role claims ASPNET_USER_ROLE_CLAIMS
User logins ASPNET_USER_LOGINS
User tokens ASPNET_USER_TOKENS
User IDs SEQ_ASPNET_USERS
Role IDs SEQ_ASPNET_ROLES
User claim IDs SEQ_USER_CLAIMS
Role claim IDs SEQ_ROLE_CLAIMS

Names can be overridden in AddOracle11GConnectionFactory:

.AddOracle11GConnectionFactory(options =>
{
    options.ConnectionString = connectionString;
    options.DbSchema = "IDENTITY";
    options.UsersTableName = "APP_USERS";
    options.RolesTableName = "APP_ROLES";
    options.UsersSequence = "SEQ_APP_USERS";
    options.RolesSequence = "SEQ_APP_ROLES";
});

ConnectionString is required. When supplied, DbSchema is trimmed, normalized to uppercase, and has [, ], and backtick SQL identifier quoting characters stripped. Table and sequence names can all be overridden through DbProviderOptions; supply valid Oracle identifiers.

Database constraints should enforce the same logical uniqueness used by the stores:

  • User claims: (UserId, ClaimType, ClaimValue)
  • Role claims: (RoleId, ClaimType, ClaimValue)
  • User roles: (UserId, RoleId)
  • External logins: (LoginProvider, ProviderKey)
  • User tokens: (UserId, LoginProvider, Name)

License

Licensed under the MIT License.

Product 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 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 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 netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 111 9/8/2026
1.0.6 101 9/7/2026