EF Core 实现多租户

SAAS 和多租户

SaaS(软件及服务)区别于其他应用程序的主要特征就是能够使客户在使用应用程序时按照使用量付费。他们不需要为软件购买许可,也不需要安装、托管和管理它。这方面的操作全部由提供 SaaS 软件的组织负责。

多租户是实现 SaaS 的关键因素, 它可以让多个企业或组织用户共用相同的系统或程序组件, 同时不会破坏这些组织的数据的安全性, 确保各组织间数据的隔离性.

多租户数据隔离方案

  1. 单数据库

    如果软件系统仅部署一个实例,并且所有租户的数据都是存放在一个数据库里面的,那么可以通过一个 TenantId (租户 Id) 来进行数据隔离。那么当我们执行 SELECT 操作的时候就会附加上当前登录用户租户 Id 作为过滤条件,那么查出来的数据也仅仅是当前租户的数据,而不会查询到其他租户的数据。

    这是共享程度最高、隔离级别最低的模式。需要在设计开发时加大对安全的开发量。

    640?wx_fmt=png

  2. 多数据库

    为每一个租户提供一个单独的数据库,在用户登录的时候根据用户对应的租户 ID,从一个数据库连接映射表获取到当前租户对应的数据库连接字符串,并且在查询数据与写入数据的时候,不同租户操作的数据库是不一样的。

    这种方案的用户数据隔离级别最高,安全性最好,但维护和购置成本较高.

    640?wx_fmt=png

也有一种介于两者之间的方案: 共享数据库,独立 Schema. 但实际应用的应该不多.

使用 EF Core 简单实现多租户

租户 Id 的获取可以采用两种方法:

  • 根据登录用户获取. 作为登录用户的附加信息, 比如把租户 Id 放到Json Web Token里面或者根据用户 Id 去数据库里取对应的租户 Id.

  • 根据企业或组织用户的Host获取. 部署的时候会给每个企业或组织分配一个单独的Host, 并在数据库里维护着一个租户 Id 和 Host 的映射表. 查询的时候根据 Host 去取对应的租户 Id.

在框架编写的时候, 我们最好能把对租户 Id 的处理(查询时候的过滤和保存时候的赋值) 放在数据访问的最底层自动实现. 从而让业务逻辑的开发人员尽量少的去关注租户 Id, 而是像开发普通应用一样去开发多租户应用.

EF Core 在2.0版本引入了"模型级别查询筛选器”的新功能, 此功能可以帮助开发人员方便实现软删除和多租户等功能.

单数据库实现

下面使用 EF Core 简单实现一个单数据库多租户的 Demo. 采用 Host 获取租户 Id.

  1. 创建 Tenant 实体类和 TenantsContext, 用于存储租户 Id 和 Host 的映射, 并根据 Host 从数据库里获取 Id.

640?wx_fmt=png

640?wx_fmt=png

创建 TenantProvider, 用于从 HttpContext 中识别 Host, 并访问 TenantsContext 获取 租户 Id.

640?wx_fmt=png

创建 Blog 实体类和 BloggingContext. 有几个注意点

  • BaseEntity 类里面包含 TenantId, 所以需要共享数据的表都要继承自这个基类.

  • BloggingContext 的构造函数里面加入参数 ITenantProvider tenantProvider, 用于获取租户 Id.

  • 在 OnModelCreating 方法里面对所有继承于 BaseEntity 的实体类配置全局过滤 builder.Entity<T>().HasQueryFilter(e => e.TenantId == _tenantId).

  • 重载 SaveChangesAsync 等方法, 保存数据的时候自动赋值 TenantId.

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

  1. 在 Startup 里面配置依赖注入

    services.AddDbContext<TenantsContext>(option => option.UseSqlServer(connectionString));
    services.AddDbContext<BloggingContext>(option => option.UseSqlServer(connectionString));
    services.AddScoped<ITenantProvider, TenantProvider>();
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

多数据库实现

多数据的实现也不复杂, 在 Tenant 实体类里面加入新的字段 DatabaseConnectionString 用于存放每个租户的数据库连接字符串, 在 BloggingContext 的 OnConfiguring 方法里面根据获取的 Tenant 配置连接字符串.

640?wx_fmt=png

这只是一个简单的实现, 多租户系统需要关注的点还有蛮多, 比如租户的注册, 功能订阅, 计费, 数据备份, 统一管理等...

源代码

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源码分析多租户体系与权限验证

  • 将您的 web 应用程序转化为多租户 SaaS 解决方案

原文地址: https://www.cnblogs.com/royzshare/p/9958888.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3246 [HNOI2016]序列(莫队+单调栈+ST表)

[HNOI2016]序列 Tea神题解 Kelin神题解 对于莫队算法最主要的是如何快速算出[l,r]→[l,r1][l,r]\to[l,r1][l,r]→[l,r1]对答案的贡献的变化。 当询问区间发生上述变化时[l,r]→[l,r1][l,r]\to [l,r1][l,r]→[l,r1]不难发现子区间增加这些&#xff1a;[l,r1],[l1,r1],…,[r,r1…

P6672-[清华集训2016]你的生命已如风中残烛【结论】

正题 题目链接:https://www.luogu.com.cn/problem/P6672 题目大意 长度为mmm的序列aaa&#xff0c;有nnn个数字不是000&#xff0c;其他m−nm-nm−n个是000。要求重排后有多少方案满足 ∀x,∑i1xai≥i\forall x,\sum_{i1}^xa_i\geq i∀x,i1∑x​ai​≥i 其中m∑i1naim\sum_{i…

牛客题霸 反转链表 C++题解/答案

题目描述 输入一个链表&#xff0c;反转链表后&#xff0c;输出新链表的表头。 示例1 输入 复制 {1,2,3} 返回值 复制 {3,2,1} 题解&#xff1a; 如果用偷懒的方法&#xff0c;可以用vector来存链表内容&#xff0c;然后来个翻转&#xff08;vector自带&#xff09;即可 但是…

【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis

上篇文章【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置&#xff08;2&#xff09;我们介绍了2种网关配置信息更新的方法和扩展Mysql存储&#xff0c;本篇我们将介绍如何使用Redis来实现网关的所有缓存功能&#xff0c;用到的文档及源码将会在GitHub上开源&a…

P5934-[清华集训2012]最小生成树【最小割】

正题 题目链接:https://www.luogu.com.cn/problem/P5934 题目大意 给出nnn个点mmm条边的一张图&#xff0c;再加入一条边(u,v,L)(u,v,L)(u,v,L)求至少删掉多少条边可以使得这条边即在最小生成树上又在最大生成树上。 1≤n≤2104,1≤m≤21051\leq n\leq 2\times 10^4,1\leq m\…

广州.net俱乐部12月份ABP框架活动场地征集、志愿者征集、合作讲师\副讲师征集...

大家好&#xff0c;我在<被低估的.net(上) - 微软MonkeyFest 2018广州分享会活动回顾>一文中提到&#xff0c;我将在12月份搞一场ABP框架活动&#xff0c;现向大家征集活动场地、志愿者、合作讲师\副讲师。活动课程标题是&#xff1a;如何用ABP框架快速完成项目这是内容大…

4152. [AMPPZ2014]The Captain(稠密图最短路)

4152. [AMPPZ2014]The Captain 显然稠密图的边数时n2n^2n2量级&#xff0c;我们不可能把所有边建立出来&#xff0c;这时候通常寻求一些性质详细见【论题选编】稠密图最短路 针对本题我们可以先这样考虑&#xff0c;假设每个点有且只有一维信息&#xff0c;那么任意两点之间的…

牛客题霸 二分查找 C++题解/答案

牛客题霸 二分查找 C题解/答案 题目描述 请实现有重复数字的有序数组的二分查找。 输出在数组中第一个大于等于查找值的位置&#xff0c;如果数组中不存在这样的数&#xff0c;则输出数组长度加一。 示例1 输入 复制 5,4,[1,2,4,4,5] 返回值 复制 3 题解&#xff1a; 二分模…

CF1446F-Line Distance【计算几何,树状数组,二分】

正题 题目链接:https://www.luogu.com.cn/problem/CF1446F 题目大意 给出nnn个点&#xff0c;求所有点对构成的直线中与原点距离第kkk小的距离 2≤n≤105,1≤k≤n(n−1)22\leq n\leq 10^5,1\leq k\leq \frac{n(n-1)}{2}2≤n≤105,1≤k≤2n(n−1)​ 解题思路 二分还是挺显然的…

牛客题霸 判断链表中是否有环 C++题解/答案

牛客题霸 判断链表中是否有环 C题解/答案 题目描述 判断给定的链表中是否有环 扩展&#xff1a; 你能给出空间复杂度的解法么&#xff1f; 题解&#xff1a; 在这介绍一个简便的方法&#xff1a;快慢指针 就是&#xff1a;一个指针走两步&#xff0c;一个指针走一步 快慢指…

为什么是容器,Docker和Kubernetes?

如果你是一名IT行业的从业者&#xff0c;还没有听说过以上3个词的任何一个&#xff0c;抱歉&#xff0c;你可以改行了&#xff1b;如果你是一名技术人员&#xff0c;无论你是程序员&#xff0c;测试人员&#xff0c;运维工程师还是时髦的DevOps工程师&#xff0c;你还没有运行过…

P2685 [TJOI2012]桥(最短路+线段树)

P2685 [TJOI2012]桥 xcxcli题解 下面思路仿照上述题解&#xff0c;代码基本照抄上述题解 u⇝vu\leadsto vu⇝v表示uuu到vvv的最短路 u→vu\to vu→v表示uuu和vvv直接相连的边 d1ud1_ud1u​表示1⇝u1\leadsto u1⇝u的最短路 dnudn_udnu​表示n⇝vn\leadsto vn⇝v的最短路 题意化…

牛客题霸 [斐波那契数列] C++题解/答

斐波那契数列 题目描述 大家都知道斐波那契数列&#xff0c;现在要求输入一个整数n&#xff0c;请你输出斐波那契数列的第n项&#xff08;从0开始&#xff0c;第0项为0&#xff0c;第1项是1&#xff09;。 n<39 题解&#xff1a; 斐波那契数列。。递推的基础题目 众所周…

一份来自28岁.NET老程序员的自白

写在前面很幸运&#xff0c;28岁的我头发还没有掉光&#xff0c;更幸运的是28岁的我开始了博客园的写作生活&#xff01;这样的技术分享经历让我拓展了自己的朋友圈&#xff01;有幸结识了像张善友张队&#xff08;连续13年的微软MVP&#xff09;&#xff0c;大石头(NewLife团队…

P5825-排列计数【EGF,NTT】

正题 题目链接:https://www.luogu.com.cn/problem/P5825 题目大意 对于每个kkk&#xff0c;求有多少个长度为nnn的排列有kkk个位置上升。 1≤n≤21051\leq n\leq 2\times 10^51≤n≤2105 解题思路 考虑到同时考虑大于和小于十分麻烦&#xff0c;设fif_ifi​表示钦定iii个上升…

牛客题霸 [数组中出现次数超过一半的数字] C++题解/答案

牛客题霸 [数组中出现次数超过一半的数字] C题解/答案 题解&#xff1a; 题意很明确 跑一遍for循环&#xff0c;统计每个数出现的大小 然后再跑一边循环&#xff0c;查看是否存在大于一半的情况 注意题目要求是大于&#xff0c;没有等于 代码&#xff1a; class Solution {…

2725. [Violet 6]故乡的梦(删边最短路同[TJOI2012]桥)

2725. [Violet 6]故乡的梦 和P2685 [TJOI2012]桥可以说是一模一样&#xff0c;判断u,vu,vu,v是否在最短路径上可以利用之前预处理的id[]详细看代码。 #include<map> #include<queue> #include<cstring> #include<iostream> #include<algorithm>…

谈谈.NET Core中基于Generic Host来实现后台任务

前言很多时候&#xff0c;后台任务对我们来说是一个利器&#xff0c;帮我们在后面处理了成千上万的事情。在.NET Framework时代&#xff0c;我们可能比较多的就是一个项目&#xff0c;会有一到多个对应的Windows服务&#xff0c;这些Windows服务就可以当作是我们所说的后台任务…

P3971-[TJOI2014]Alice and Bob【贪心】

正题 题目链接:https://www.luogu.com.cn/problem/P3971 题目大意 一个1∼n1\sim n1∼n的一个排列&#xff0c;设aia_iai​表示以iii结尾的最长上升子序列长度&#xff0c;bib_ibi​表示以iii开头的最长下降子序列长度。 给出序列aaa求序列bbb的最大和。 1≤n≤1051\leq n\l…

牛客题霸 [平衡二叉树] C++题解/答案

牛客题霸 [平衡二叉树] C题解/答案 题目描述 输入一棵二叉树&#xff0c;判断该二叉树是否是平衡二叉树。 在这里&#xff0c;我们只需要考虑其平衡性&#xff0c;不需要考虑其是不是排序二叉树 题解&#xff1a; 今天上数据结构刚考了平衡二叉树 平衡二叉树定义(AVL)&…