ABP是一个成熟的.NET框架,功能完善。目前由于项目需要正在自学中。

ABP对于组织节点管理这一基本上每个项目都要反复重复开发的内容,进行了自己的实现。

主要包括这些常用功能:

  • 多租户
  • 树结构管理的实体
  • 与用户系统集成的查询

下面我们根据官方文档以及DEMO去学习这个功能。

不过需要注意的是,ABP默认没有提供展示层的实现,这一块就需要自己实现了。

官方文档理解

OrganizationUnit 实体定义

  • TenantId: 租户ID,如果为null则是host的组织节点。(具体概念参阅多租户)
  • ParentId: 父节点Id,如果为null则是根节点。
  • Code: 一个拼接的虚拟路径字符串代码,在租户内唯一。
  • DisplayName: 显示名称

Organization Tree

模型定义中的ParentId使得这个数据结构定义了一个典型的父子树。

  • 这个树允许有多个根节点
  • 树的最大深度是OrganizationUnit.MaxDepth,值为16
  • 每一级子节点的数目也有限制,主要是由于后面要提到的OU Code定义决定的。

OU Code

OU Code由OrganizationUnit Manager自动维护,它是类似于"00001.00042.00005"的字符串。它可以用于递归查询。

这种字段在树结构中是很必须的,如果没有它,树查询会变成效率的杀手。有了这类虚拟路径,可以通过分隔符分解后批量查询。

Abp对OU Code有以下规则:

  • 在一个租户中唯一
  • 子节点的Code需要以父节点的Code开头
  • Code的长度,由层级深度决定
  • OU Code可以被改变,例如移动节点
  • 我们需要使用Id作为OU引用的字段,而不是Code

OrganizationUnit Manager

  • OrganizationUnitManager 通过依赖注入引入,一般用于:
  • 增、删、改OU
  • 移动OU
  • 读取OU信息,以及OU的items

Multi-Tenancy

OrganizationUnitManager 一次只能操作一个租户,默认租户为当前租户。

样例代码分析

首先创建一个实体,派生自IMustHaveTenant , IMustHaveOrganizationUnit

public class Product : Entity, IMustHaveTenant, IMustHaveOrganizationUnit
{
public virtual int TenantId { get; set; } public virtual long OrganizationUnitId { get; set; } public virtual string Name { get; set; } public virtual float Price { get; set; }
}

  

实现Service:

public class ProductManager : IDomainService
{
//实体仓储,实体继承自IMustHaveOrganizationUnit
private readonly IRepository<Product> _productRepository;
//OU仓储,通过此仓储读取OU
private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
//用户数据Manager
private readonly UserManager _userManager; //构造函数,DI注入
public ProductManager(
IRepository<Product> productRepository,
IRepository<OrganizationUnit, long> organizationUnitRepository,
UserManager userManager)
{
_productRepository = productRepository;
_organizationUnitRepository = organizationUnitRepository;
_userManager = userManager;
} //根据组织节点,获取关联的Product
public List<Product> GetProductsInOu(long organizationUnitId)
{
return _productRepository.GetAllList(p => p.OrganizationUnitId == organizationUnitId);
} //根据组织节点Id查询所有的Products,包含子Product
[UnitOfWork]//UnitOfWork支持事务
public virtual List<Product> GetProductsInOuIncludingChildren(long organizationUnitId)
{
//根据组织节点id,获取code
var code = _organizationUnitRepository.Get(organizationUnitId).Code; //查询组织节点开头的所有节点,这样避免了递归查询,提升了效率,也是Code定义的目的所在
var query =
from product in _productRepository.GetAll()
join organizationUnit in _organizationUnitRepository.GetAll() on product.OrganizationUnitId equals organizationUnit.Id
where organizationUnit.Code.StartsWith(code)
select product; return query.ToList();
} //根据用户查询Product
//查询用户关联的组织节点,再根据组织节点,查询关联的Product
public async Task<List<Product>> GetProductsForUserAsync(long userId)
{
var user = await _userManager.GetUserByIdAsync(userId);
var organizationUnits = await _userManager.GetOrganizationUnitsAsync(user);
var organizationUnitIds = organizationUnits.Select(ou => ou.Id); return await _productRepository.GetAllListAsync(p => organizationUnitIds.Contains(p.OrganizationUnitId));
} //同上个函数类似,查询中加入了子节点
[UnitOfWork]
public virtual async Task<List<Product>> GetProductsForUserIncludingChildOusAsync(long userId)
{
var user = await _userManager.GetUserByIdAsync(userId);
var organizationUnits = await _userManager.GetOrganizationUnitsAsync(user);
var organizationUnitCodes = organizationUnits.Select(ou => ou.Code); var query =
from product in _productRepository.GetAll()
join organizationUnit in _organizationUnitRepository.GetAll() on product.OrganizationUnitId equals organizationUnit.Id
where organizationUnitCodes.Any(code => organizationUnit.Code.StartsWith(code))
select product; return query.ToList();
}
}

  

  

通过这段源码我们发现,其实在Abp模板中Zero模块已经默认添加了用户与组织节点的关联,如下图:

OrganizationUnits表是一个父子树结构,表达了我们系统中所有需要以父子树表达的逻辑结构。

实体表User,Product通过一张关联表与组织节点关联,关联关系如E-R图所示。

在数据库中,abp并没有创建外键联系,这应该是为了高复用OU表。

其他设置

你可以通过 AbpZeroSettingNames.OrganizationUnits.MaxUserMembershipCount 来设置一个用户的最大OU关联数。

AspnetBoilerplate (ABP) Organization Units 组织结构管理的更多相关文章

  1. X-Admin&ABP框架开发-设置管理

    在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...

  2. ABP.ModuleZero.Feature——特性管理

    原文地址:http://aspnetboilerplate.com/Pages/Documents/Feature-Management  (在翻译原文的基础上增补更多细节说明) 简介 在大多数SAA ...

  3. ABP理论学习之设置管理

    返回总目录 本篇目录 介绍 定义设置 获取设置值 更改设置 关于缓存 介绍 每个应用程序都需要存储一些设置信息,然后在应用程序中的某个地方使用这些设置.ABP提供了健壮的基础设施来存储或检索服务端和客 ...

  4. ABP Zero 多租户管理

    ABPZero - 多租户管理 启用多租户 ASP.NET Boilerplate和module-zero可以运行多租户或单租户模式.多租户默认为禁用.我们可以在我们的模块PreInitialize方 ...

  5. X-Admin&ABP框架开发-租户管理

    软件即服务概念的推动,定制化到通用化的发展,用一套代码完成适应不同企业的需求,利用多租户技术可以去做到这一点.ABP里提供了多租户这一概念并且也在Zero模块中实现了这一概念. 一.多租户的概念 单部 ...

  6. ABP理论学习之功能管理

    返回总目录 本篇目录 介绍 功能类型 定义功能 检查功能 功能管理者 版本说明 介绍 大多数的Saas(多租户)应用都有不同 功能的 版本(包).因此,他们可以给租户(客户)提供不同的 价格和功能选项 ...

  7. Orchard 与 ABP架构比较 (aspnetboilerplate)

    前言:  ABP框架经常在一些.NET群中听群友提起,以前也浏览过官网,大致了解它是一个框架,直到今天本人才正式下载源码入门 ... 经过两个小时的ABP中文文档入门(感谢各位辛勤的翻译者) ,大致了 ...

  8. ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理

    在前面两篇随笔<ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理>和<ABP开发框架前后端开发系列---(8)ABP框架之Winform界面的开发过程>开始 ...

  9. 吐槽一下Abp的用户和租户管理模块

    1. 背景 ASP.NET Core 基于声明的访问控制到底是什么鬼? 聊到基于声明的身份认证将 身份和签发机构分离,应用程序信任签发机构,故认可签发的身份信息. -- --- --- --- Cla ...

随机推荐

  1. Joker的运维开发之路

    python 1--数据类型,流程控制 2--数据类型详细操作,文件操作,字符编码 https://mp.weixin.qq.com/s/i3lcIP82HdsSr9LzPgkqww 点开更精彩 目前 ...

  2. 使用CSS3 Flexbox布局

    Flexbox(中文版本可以点击这里)的布局是一个用于页面布局的全新CSS3模块功能.它可以把列表放在同一个方向(从左到右或从上到下排列),并且让这些列表能延伸到占用可用的空间.较为复杂的布局可以通过 ...

  3. JAVA中构造函数的参数传递给类中的实例变量

    class VolcanoRobot1 { String status; int speed; float temperature; VolcanoRobot1(int speed,float tem ...

  4. 关于linux网络基础记录

    1.linux操作系统是一套非常稳定的操作系统,作用永不止于提供网络服务那么简单.(www.Mail.FTP.DNS.DHCP.NAT.Router) 2.对于一个服务器而言,“搭建容易维护难”:维护 ...

  5. mac下mysql5.7.18修改root密码

    参考:http://blog.csdn.net/lijilong_/article/details/70991809 第一步:苹果->系统偏好设置->最下面点MySQL,关闭mysql服务 ...

  6. split分隔

    split() : 把一个字符串分割成字符串数组 <script> var str="name=ww;value=ll"; var mm=str.split(" ...

  7. 关于C++成员函数指针的使用

    在做项目的时候,遇到了在类中根据不同的调用函数,在被调用函数的某处需要做不同的处理,本来就想着直接在类中设个标记变量判断下就好了,不过觉得这样代码可能看起来会有些凌乱,而且效率估计有些低,于是想起来使 ...

  8. 小米手机Root 刷机

    需要备份的资料: miui系统资料:电话.短信.便签,有小米云账号wifi下自己会备份好的. 应用数据:微信.qq 聊天记录: UC浏览器收藏夹. root后, rootexplorer,选择某个文件 ...

  9. MySQL Innodb 神秘消失

    问题描述: 早晨接到 Zabbix 报警,提示 Host: 10.10.1.2, MySQL 主从同步失败. 登录服务器查看具体情况. shell > mysql mysql> show ...

  10. Lnmp 源码编译安装、常见错误整理

    简介: Lnmp 环境的搭建还是非常简单的,之前由于博客迁移等原因,导致丢失了好多博文,这次重新整理记录一下. Lnmp 即:Linux .Nginx .Mysql .PHP Lnmp 是一套 Web ...