TCIS.Pluggable.Persistence.Oracle 1.0.0-rc.19

This is a prerelease version of TCIS.Pluggable.Persistence.Oracle.
dotnet add package TCIS.Pluggable.Persistence.Oracle --version 1.0.0-rc.19
                    
NuGet\Install-Package TCIS.Pluggable.Persistence.Oracle -Version 1.0.0-rc.19
                    
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="TCIS.Pluggable.Persistence.Oracle" Version="1.0.0-rc.19" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TCIS.Pluggable.Persistence.Oracle" Version="1.0.0-rc.19" />
                    
Directory.Packages.props
<PackageReference Include="TCIS.Pluggable.Persistence.Oracle" />
                    
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 TCIS.Pluggable.Persistence.Oracle --version 1.0.0-rc.19
                    
#r "nuget: TCIS.Pluggable.Persistence.Oracle, 1.0.0-rc.19"
                    
#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 TCIS.Pluggable.Persistence.Oracle@1.0.0-rc.19
                    
#: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=TCIS.Pluggable.Persistence.Oracle&version=1.0.0-rc.19&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=TCIS.Pluggable.Persistence.Oracle&version=1.0.0-rc.19&prerelease
                    
Install as a Cake Tool

TCIS.Pluggable.Persistence.Oracle

Oracle provider for the Pluggable multi-tenant data layer. Supports all three tiers — Virtual Private Database, schema per tenant, and database per tenant.

Shared behaviour — model composition, query filters, audit stamping — lives in TCIS.Pluggable.Persistence.EntityFrameworkCore.


1. Registration

dotnet add package TCIS.Pluggable.Persistence.Oracle
builder.Services.AddPluggableOracle<TosDbContext>(commandTimeoutSeconds: 30);

Do not pass a connection string. It is resolved per request from the Tenant Store through IMultiTenantContextAccessor<TenantInfo>.


2. Tier support

Tier Mechanism Identifier used
Tier 1 — Row level (VPD) DBMS_SESSION.SET_CONTEXT('TCIS_CTX', 'TENANT_ID', …) TenantInfo.Id (GUID)
Tier 2 — Schema per tenant ALTER SESSION SET CURRENT_SCHEMA TenantInfo.Identifier (site code)
Tier 3 — Database per tenant no-op initializer

Tier 2 takes the schema name from TenantInfo.Identifier, not TenantInfo.Id. The identifier becomes an Oracle schema name and must pass the identifier whitelist; a GUID contains - and is always rejected.

In Oracle a schema is a user, so Tier 2 means one database user per tenant. Grant the application account the privileges to switch into each of them, and nothing more.


3. Tier 1 — application context and VPD

OracleRlsConnectionInitializer sets an application context on Open() and clears it on Close(). Your VPD policy function reads it back:

CREATE OR REPLACE FUNCTION sec.tenant_predicate(
    schema_name IN VARCHAR2, table_name IN VARCHAR2) RETURN VARCHAR2 AS
BEGIN
    RETURN 'TENANT_ID = SYS_CONTEXT(''TCIS_CTX'', ''TENANT_ID'')';
END;

The context namespace TCIS_CTX must be created with a trusted package so that only that package can set it — otherwise any session could set its own tenant id and defeat the policy:

CREATE CONTEXT TCIS_CTX USING sec.tenant_ctx_pkg;

A blank tenant id runs the cleanup command, clearing any context left over from a pooled session. The predicate then matches no row: fail-closed.


4. Tier status

Tier 3 is the simplest design here (a no-op initializer) but has no automated test coverage yet, and tenant resolution is its single point of failure — if the wrong connection string is resolved, nothing downstream will catch it. Ironically it is also the tier most likely to be chosen by a large port.

Treat a Tier 3 rollout as needing its own isolation test before go-live.


5. Pitfalls

# Pitfall Consequence
1 Using a GUID as the Tier 2 identifier Whitelist rejection — use the site code
2 Creating TCIS_CTX without a trusted package Any session can set its own tenant id and bypass VPD
3 Granting the application account EXEMPT ACCESS POLICY VPD no longer applies to it — the defence is gone
4 Assuming the EF query filter protects Dapper queries It does not; on Tier 1 only VPD stands in the way
5 Relying on commandTimeoutSeconds for Dapper It applies to EF Core only
6 Deploying Tier 3 without an isolation test Tenant resolution is the only thing preventing a cross-tenant connection

6. A note on terminology

FORCE ROW LEVEL SECURITY and BYPASSRLS are PostgreSQL concepts and have no Oracle equivalent. The Oracle counterparts are VPD policies plus the EXEMPT ACCESS POLICY privilege — do not port a PostgreSQL checklist verbatim.

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 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. 
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.0-rc.19 10 8/13/2026
1.0.0-rc.18 6 8/13/2026
1.0.0-rc.17 18 8/13/2026
1.0.0-rc.16 32 8/13/2026
1.0.0-rc.15 38 8/12/2026
1.0.0-rc.14 46 8/12/2026
1.0.0-rc.13 40 8/11/2026
1.0.0-rc.12 47 8/10/2026
1.0.0-rc.11 61 7/28/2026
1.0.0-rc.10 54 7/24/2026
1.0.0-rc.9 51 7/21/2026
1.0.0-rc.8 51 7/21/2026