ABP框架中UnitOfWorkManager.Current.SetTenantId()并不是修改AbpSession.TenantId的值

发布时间 2023-06-16 14:31:03作者: 汪小让

1. 结论

UnitOfWorkManager.Current.SetTenantId()修改的是ABP过滤器中使用的TenantId,并不会修改AbpSession.TenantId

代码演示:

image
image

2. 关于UnitOfWorkManager.Current.SetTenantId()方法的作用

  • 前提:ABP框架是是支持多租户的,对于单数据库的多租户设计,需要通过TenantId来区分宿主和租户,并且ABP支持自动过滤租户数据(详情请查阅官方文档)

  • 当执行一个数据库查询(如:_deviceRepository.GetAll();)时,会自动取AbpSession.TenantId添加到查询条件中,而UnitOfWorkManager.Current.SetTenantId(_tenantId)的之后,ABP的过滤器会优先使用_tenantId,但AbpSession.TenantId不会改变

  • 如果在添加/修改的时候,需要用到SetTenantId之后的_tenantId怎么办呢?反正是不能直接用AbpSession.TenantId

    • 两个办法:
      1. 使用UnitOfWorkManager.Current.GetTenantId()获取;
      2. 直接使用_tenantId变量

3. 通常使用方式

通常和using一起使用,在using语句块运行完后,过滤器会自动从AbpSession.TenantId取租户Id,如果没有特殊需求,推荐此用法

public async Task<List<Device>> GetDevices(int tenantId)
{
   using (UnitOfWorkManager.Current.SetTenantId(tenantId))
   {
       return _deviceRepository.GetAllAsync();  //使用的是tenantId过滤
   }   
}

4. 优点

  1. 不需要手动写TenantId查询条件,尤其是涉及到多个查询的时候,优点更为明显
  2. 配合using使用,可以灵活查询不同租户Id的数据