文章目录

  • 多租户
  • APP模板
  • Module模板
  • 系统提供的租户解析器
  • 样例
  • 添加域名解析的方式
  • 实体需要做的事情
  • 如何禁用多租户数据过滤
  • 多租户分库存储
  • 数据表手动insert
  • 管理员界面配置
  • 求助

多租户

这是一个传统企业中比较常见的业务需求,总分公司结构数据总分存储和同步的问题。系统上的数据划分体现的就是多租户的情况。

APP模板

在App模板下多租户是自动开启的,所以完全不用修改任何功能。

Module模板

在Module模板下,需要修改MultiTenancyConsts中的IsEnabled=true;

项目文件结构如下

租户后端开源java框架 前端多租户_租户后端开源java框架

系统提供的租户解析器

  • CurrentUserTenantResolveContributor: 如果当前用户已登录,从当前用户的声明中获取租户Id. 出于安全考虑,应该始终将其做为第一个Contributor.
  • QueryStringTenantResolveContributor: 尝试从query string参数中获取当前租户,默认参数名为"__tenant".
  • RouteTenantResolverContributor:尝试从当前路由中获取(URL路径),默认是变量名是"__tenant".所以,如果你的路由中定义了这个变量,就可以从路由中确定当前租户.
  • HeaderTenantResolverContributor: 尝试从HTTP header中获取当前租户,默认的header名称是"__tenant".
  • CookieTenantResolverContributor: 尝试从当前cookie中获取当前租户.默认的Cookie名称是"__tenant".
  • DomainTenantResolveContributor:尝试从二级域名进行解析

样例

租户后端开源java框架 前端多租户_当前用户_02


上图中通过TenantKey修改默认的参数名称,可以避免在nginx反向代理时出现的错误

添加域名解析的方式

options.AddDomainTenantResolver("{0}.mydomain.com");

实体需要做的事情

继承 IMultiTenant

public class Product : FullAuditedAggregateRoot<Guid>, IMultiTenant
    {
        public string ProductName { get; set; }
        public string ProductUnit { get; set; }
        public string ProductDescription { get; set; }
        public decimal ProductPrice { get; set; }
        public decimal StoreNumbers { get; set; }
        public string Note { get; set; }

        public Guid? TenantId { get; set; }

        protected Product()
        {
        }
        public Product(Guid id)
         : base(id)
        {
        }
    }

如何禁用多租户数据过滤

通过注入IUnitOfWorkManager对象,在查询之前使用

using(_unitofwork.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
 {
 //TODO
 }

多租户分库存储

可以通过管理员页面配置来连接字符串,也可以通过数据库自己添加。

数据表手动insert

租户后端开源java框架 前端多租户_连接字符串_03

管理员界面配置

租户后端开源java框架 前端多租户_当前用户_04

求助

多租户分库存储,那么租户数据库的结构怎么生成呢,我是通过修改连接字符串,重新做了update-database 生成的租户库