TCIS.Pluggable.Persistence.EntityFrameworkCore
1.0.0-rc.15
dotnet add package TCIS.Pluggable.Persistence.EntityFrameworkCore --version 1.0.0-rc.15
NuGet\Install-Package TCIS.Pluggable.Persistence.EntityFrameworkCore -Version 1.0.0-rc.15
<PackageReference Include="TCIS.Pluggable.Persistence.EntityFrameworkCore" Version="1.0.0-rc.15" />
<PackageVersion Include="TCIS.Pluggable.Persistence.EntityFrameworkCore" Version="1.0.0-rc.15" />
<PackageReference Include="TCIS.Pluggable.Persistence.EntityFrameworkCore" />
paket add TCIS.Pluggable.Persistence.EntityFrameworkCore --version 1.0.0-rc.15
#r "nuget: TCIS.Pluggable.Persistence.EntityFrameworkCore, 1.0.0-rc.15"
#:package TCIS.Pluggable.Persistence.EntityFrameworkCore@1.0.0-rc.15
#addin nuget:?package=TCIS.Pluggable.Persistence.EntityFrameworkCore&version=1.0.0-rc.15&prerelease
#tool nuget:?package=TCIS.Pluggable.Persistence.EntityFrameworkCore&version=1.0.0-rc.15&prerelease
TCIS.Pluggable.Persistence.EntityFrameworkCore
The core library providing Multi-tenancy architecture, Dynamic Model discovery, UnitOfWork, Repository, and Dapper Context built on top of Entity Framework Core for the TCIS ecosystem.
📦 Installation
dotnet add package TCIS.Pluggable.Persistence.EntityFrameworkCore
🚀 Registration / Setup (Program.cs)
Note: Do not use this package directly to register the DbContext. Please use Provider-specific packages such as
TCIS.Pluggable.Persistence.SqlServer,Oracle, orPostgreSql.
However, for custom configuration, the core extension method is:
using TCIS.Pluggable.Persistence.EntityFrameworkCore;
// Integrates GenericRepository, UnitOfWork, DapperContext, and SiteModelCacheKeyFactory
// services.AddPluggableDbContext<MyDbContext>((sp, options) => { ... });
💡 Core Interfaces Automatically Registered
When using AddPluggableDbContext, the following services will be available in the DI container:
DbContext(Mapped to your TContext)IUnitOfWorkIGenericRepository<TEntity>IDapperContext
Your DbContext classes should inherit from TBaseDbContext to inherit built-in features such as Isolation Multi-tenancy and Auditing.
🔒 Global Query Filter — Fail-Closed
Tenant filter được áp theo bảng sau. Điểm cần nhớ: thiếu WorkContext KHÔNG có nghĩa là "thấy hết mọi tenant".
Trạng thái WorkContext |
Tenant filter | Kết quả |
|---|---|---|
Có, Tier1_RowLevel |
✅ Áp | Chỉ thấy dữ liệu của tenant hiện tại |
Có, Tier2_Schema / Tier3_Database |
❌ Không | Đã cách ly ở tầng schema / database |
| Không có (Hangfire job, EventBus consumer, migration tool) | ✅ Áp | CurrentTenantId là null → truy vấn trả về rỗng |
Nhánh cuối là có chủ đích. Job nền chạy không có tenant context mà lại quét xuyên toàn bộ tenant là lỗi rò rỉ dữ liệu, không phải tiện ích.
Cross-tenant hợp lệ phải mở cửa tường minh
public class ReportingDbContext(DbContextOptions<ReportingDbContext> options, IWorkContextAccessor accessor)
: TBaseDbContext<ReportingDbContext>(options, accessor)
{
// Báo cáo toàn hệ thống / job đồng bộ — bỏ qua tenant filter một cách CÓ Ý THỨC.
protected override bool AllowCrossTenantQuery => true;
}
AllowCrossTenantQuery được đánh giá tại thời điểm truy vấn, không ảnh hưởng Model Cache — nên
có thể trỏ vào một cờ do bạn tự quản thay vì hằng số.
Mở cờ này là tắt lớp phòng thủ tenant ở tầng ứng dụng. Với Tier 1, lớp phòng thủ còn lại là RLS dưới database — hãy chắc chắn DBA đã bật.
Xem bản ghi đã xoá mềm — dùng IncludeSoftDeleted(), KHÔNG dùng IgnoreQueryFilters()
EF Core chỉ giữ một query filter cho mỗi entity, nên tenant và soft-delete buộc phải gộp chung
một biểu thức. Hệ quả: IgnoreQueryFilters() gỡ cả hai cùng lúc.
// ❌ SAI — ý định là xem thùng rác, thực tế thấy luôn đơn hàng của MỌI tenant
var deleted = await db.Orders.IgnoreQueryFilters().Where(o => o.IsDeleted).ToListAsync();
// ✅ ĐÚNG — thấy bản ghi đã xoá, tenant filter vẫn nguyên vẹn
using (db.IncludeSoftDeleted())
{
var deleted = await db.Orders.Where(o => o.IsDeleted).ToListAsync();
}
Phạm vi có đếm lồng nhau và tự đóng khi ra khỏi using. Nếu cả một DbContext vốn dành cho nghiệp
vụ lưu trữ/khôi phục, override thẳng AllowSoftDeletedQuery => true thay vì mở phạm vi ở từng chỗ.
Ở Tier 1, RLS dưới database vẫn chặn rò rỉ do IgnoreQueryFilters(). Ở Tier 3 không có
lớp nào chặn — một truy vấn trông hoàn toàn hợp lệ sẽ đọc xuyên tenant. Đây là lý do quy tắc trên
là quy tắc, không phải gợi ý.
📝 Auditing & TenantId
TBaseDbContext override SaveChanges(bool) và SaveChangesAsync(bool, CancellationToken) — hai
điểm mở rộng chính tắc của EF Core. Vì vậy cả 4 lối vào (SaveChanges(), SaveChanges(bool),
SaveChangesAsync(ct), SaveChangesAsync(bool, ct)) đều được đóng dấu Audit và tự gán TenantId.
| 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 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. |
-
net8.0
- Dapper (>= 2.1.66)
- Microsoft.EntityFrameworkCore (>= 8.0.13)
- Microsoft.EntityFrameworkCore.Relational (>= 8.0.13)
- Microsoft.Extensions.Caching.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Http (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
- Microsoft.Extensions.Options (>= 9.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 8.0.0)
- TCIS.Core (>= 1.0.0-rc.15)
- TCIS.MultiTenancy (>= 1.0.0-rc.15)
- TCIS.Persistence.EntityFrameworkCore (>= 1.0.0-rc.15)
- TCIS.Pluggable.Abstractions (>= 1.0.0-rc.15)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on TCIS.Pluggable.Persistence.EntityFrameworkCore:
| Package | Downloads |
|---|---|
|
TCIS.Pluggable.Persistence.SqlServer
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. Pluggable Persistence SqlServer |
|
|
TCIS.Pluggable.Persistence.PostgreSql
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. Pluggable Persistence PostgreSQL |
|
|
TCIS.Pluggable.Persistence.Oracle
TCIS Core Framework is an application framework for building modular, multi-tenant applications on ASP.NET Core. Pluggable Persistence Oracle |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-rc.15 | 7 | 8/12/2026 |
| 1.0.0-rc.14 | 33 | 8/12/2026 |
| 1.0.0-rc.13 | 40 | 8/11/2026 |
| 1.0.0-rc.12 | 53 | 8/10/2026 |
| 1.0.0-rc.11 | 74 | 7/28/2026 |
| 1.0.0-rc.10 | 68 | 7/24/2026 |
| 1.0.0-rc.9 | 69 | 7/21/2026 |
| 1.0.0-rc.8 | 64 | 7/21/2026 |
| 1.0.0-rc.7 | 57 | 7/17/2026 |
| 1.0.0-rc.6 | 63 | 7/7/2026 |
| 1.0.0-rc.5 | 70 | 7/7/2026 |