EF Core 实现多租户
SAAS 和多租戶
SaaS(軟件及服務(wù))區(qū)別于其他應(yīng)用程序的主要特征就是能夠使客戶在使用應(yīng)用程序時(shí)按照使用量付費(fèi)。他們不需要為軟件購買許可,也不需要安裝、托管和管理它。這方面的操作全部由提供 SaaS 軟件的組織負(fù)責(zé)。
多租戶是實(shí)現(xiàn) SaaS 的關(guān)鍵因素, 它可以讓多個(gè)企業(yè)或組織用戶共用相同的系統(tǒng)或程序組件, 同時(shí)不會(huì)破壞這些組織的數(shù)據(jù)的安全性, 確保各組織間數(shù)據(jù)的隔離性.
多租戶數(shù)據(jù)隔離方案
單數(shù)據(jù)庫
如果軟件系統(tǒng)僅部署一個(gè)實(shí)例,并且所有租戶的數(shù)據(jù)都是存放在一個(gè)數(shù)據(jù)庫里面的,那么可以通過一個(gè) TenantId (租戶 Id) 來進(jìn)行數(shù)據(jù)隔離。那么當(dāng)我們執(zhí)行 SELECT 操作的時(shí)候就會(huì)附加上當(dāng)前登錄用戶租戶 Id 作為過濾條件,那么查出來的數(shù)據(jù)也僅僅是當(dāng)前租戶的數(shù)據(jù),而不會(huì)查詢到其他租戶的數(shù)據(jù)。
這是共享程度最高、隔離級(jí)別最低的模式。需要在設(shè)計(jì)開發(fā)時(shí)加大對(duì)安全的開發(fā)量。
多數(shù)據(jù)庫
為每一個(gè)租戶提供一個(gè)單獨(dú)的數(shù)據(jù)庫,在用戶登錄的時(shí)候根據(jù)用戶對(duì)應(yīng)的租戶 ID,從一個(gè)數(shù)據(jù)庫連接映射表獲取到當(dāng)前租戶對(duì)應(yīng)的數(shù)據(jù)庫連接字符串,并且在查詢數(shù)據(jù)與寫入數(shù)據(jù)的時(shí)候,不同租戶操作的數(shù)據(jù)庫是不一樣的。
這種方案的用戶數(shù)據(jù)隔離級(jí)別最高,安全性最好,但維護(hù)和購置成本較高.
也有一種介于兩者之間的方案: 共享數(shù)據(jù)庫,獨(dú)立 Schema. 但實(shí)際應(yīng)用的應(yīng)該不多.
使用 EF Core 簡單實(shí)現(xiàn)多租戶
租戶 Id 的獲取可以采用兩種方法:
根據(jù)登錄用戶獲取. 作為登錄用戶的附加信息, 比如把租戶 Id 放到Json Web Token里面或者根據(jù)用戶 Id 去數(shù)據(jù)庫里取對(duì)應(yīng)的租戶 Id.
根據(jù)企業(yè)或組織用戶的Host獲取. 部署的時(shí)候會(huì)給每個(gè)企業(yè)或組織分配一個(gè)單獨(dú)的Host, 并在數(shù)據(jù)庫里維護(hù)著一個(gè)租戶 Id 和 Host 的映射表. 查詢的時(shí)候根據(jù) Host 去取對(duì)應(yīng)的租戶 Id.
在框架編寫的時(shí)候, 我們最好能把對(duì)租戶 Id 的處理(查詢時(shí)候的過濾和保存時(shí)候的賦值) 放在數(shù)據(jù)訪問的最底層自動(dòng)實(shí)現(xiàn). 從而讓業(yè)務(wù)邏輯的開發(fā)人員盡量少的去關(guān)注租戶 Id, 而是像開發(fā)普通應(yīng)用一樣去開發(fā)多租戶應(yīng)用.
EF Core 在2.0版本引入了"模型級(jí)別查詢篩選器”的新功能, 此功能可以幫助開發(fā)人員方便實(shí)現(xiàn)軟刪除和多租戶等功能.
單數(shù)據(jù)庫實(shí)現(xiàn)
下面使用 EF Core 簡單實(shí)現(xiàn)一個(gè)單數(shù)據(jù)庫多租戶的 Demo. 采用 Host 獲取租戶 Id.
創(chuàng)建 Tenant 實(shí)體類和 TenantsContext, 用于存儲(chǔ)租戶 Id 和 Host 的映射, 并根據(jù) Host 從數(shù)據(jù)庫里獲取 Id.
創(chuàng)建 TenantProvider, 用于從 HttpContext 中識(shí)別 Host, 并訪問 TenantsContext 獲取 租戶 Id.
創(chuàng)建 Blog 實(shí)體類和 BloggingContext. 有幾個(gè)注意點(diǎn)
BaseEntity 類里面包含 TenantId, 所以需要共享數(shù)據(jù)的表都要繼承自這個(gè)基類.
BloggingContext 的構(gòu)造函數(shù)里面加入?yún)?shù) ITenantProvider tenantProvider, 用于獲取租戶 Id.
在 OnModelCreating 方法里面對(duì)所有繼承于 BaseEntity 的實(shí)體類配置全局過濾?builder.Entity<T>().HasQueryFilter(e => e.TenantId == _tenantId).
重載 SaveChangesAsync 等方法, 保存數(shù)據(jù)的時(shí)候自動(dòng)賦值 TenantId.
在 Startup 里面配置依賴注入
services.AddDbContext<TenantsContext>(option => option.UseSqlServer(connectionString)); services.AddDbContext<BloggingContext>(option => option.UseSqlServer(connectionString)); services.AddScoped<ITenantProvider, TenantProvider>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();多數(shù)據(jù)庫實(shí)現(xiàn)
多數(shù)據(jù)的實(shí)現(xiàn)也不復(fù)雜, 在 Tenant 實(shí)體類里面加入新的字段 DatabaseConnectionString 用于存放每個(gè)租戶的數(shù)據(jù)庫連接字符串, 在 BloggingContext 的 OnConfiguring 方法里面根據(jù)獲取的 Tenant 配置連接字符串.
這只是一個(gè)簡單的實(shí)現(xiàn), 多租戶系統(tǒng)需要關(guān)注的點(diǎn)還有蠻多, 比如租戶的注冊(cè), 功能訂閱, 計(jì)費(fèi), 數(shù)據(jù)備份, 統(tǒng)一管理等...
源代碼
github:https://github.com/zdz72113/NETCore_BasicKnowledge.Examples/tree/master/ORMDemo/ORMDemo.MultiTenancy?
參考
EntityFrameworkCore.samples.QueryFilters
Global query filters in Entity Framework Core 2.0
Abp源碼分析多租戶體系與權(quán)限驗(yàn)證
將您的 web 應(yīng)用程序轉(zhuǎn)化為多租戶 SaaS 解決方案
原文地址: https://www.cnblogs.com/royzshare/p/9958888.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的EF Core 实现多租户的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【招聘(上海)】东方财富证券招聘.net
- 下一篇: 【.NET Core项目实战-统一认证平