在ASP.NET Core中实现OrganizationUnitfilter

在ASP.NET Boilerplate中,有像Tenantfilter这样的内置数据filter,我们可以使用SetTenantId来启用查询特定的tenantId

根据官方文档,与EF 6.x不同,它不支持EF Core中的自定义Filter

我想知道如何为OrganizationUnitId参数实现类似的filter。

这是我到目前为止所做的:

  1. 覆盖CreateFilterExpression

     protected override Expression<Func> CreateFilterExpression() { Expression<Func> expression = null; if (typeof(IMayHaveOrganizationUnit).IsAssignableFrom(typeof(TEntity))) { Expression<Func> mayHaveOUFilter = e => ((IMayHaveOrganizationUnit)e).OrganizationUnitId == CurrentOrganizationUnitId || (((IMayHaveOrganizationUnit)e).OrganizationUnitId == CurrentOrganizationUnitId) == IsMayHaveOrganizationUnitFilterEnabled; expression = expression == null ? mayHaveOUFilter : CombineExpressions(expression, mayHaveOUFilter); } expression = expression == null ? base.CreateFilterExpression() : CombineExpressions(expression, base.CreateFilterExpression()); return expression; } 
  2. 我通过以下代码注册新filter:

     Configuration.UnitOfWork.RegisterFilter("MayHaveOrganizationUnit", true); 

但是,我如何实现代码来设置OrganizationUnitId

SetTenantId用于配置tenantId ,如何从UnitOfWork配置OrganizationUnitId

  1. 我尝试inheritanceClaimsAbpSession如下所示:

     public class CustomAbpSession : ClaimsAbpSession, ICustomAbpSession { private readonly IRepository _userRepository; public CustomAbpSession( IRepository userRepository, IPrincipalAccessor principalAccessor, IMultiTenancyConfig multiTenancy, ITenantResolver tenantResolver, IAmbientScopeProvider sessionOverrideScopeProvider) : base(principalAccessor, multiTenancy, tenantResolver, sessionOverrideScopeProvider) { _userRepository = userRepository; } public virtual long? OrganizationUnitId { get { if (UserId != null) { var user = _userRepository.Get(UserId.Value); return 1; } return null; } } public long? ImpersonatorOrganizationUnitId => throw new NotImplementedException(); } 
     protected virtual long? GetCurrentOrganizationUnitIdOrNull() { return 3; // ((ICustomAbpSession)AbpSession).OrganizationUnitId; } 
  2. 使用下面的代码注册自定义IAbpSession

     Configuration.ReplaceService(typeof(IAbpSession), () => { IocManager.Register(DependencyLifeStyle.Transient); }); 

用法:

 public List GetAll() { using (CurrentUnitOfWork.SetFilterParameter("MayHaveOrganizationUnit", "OrganizationUnitId", 2)) { return _productRepositry.GetAll().ToList(); } } 

但是,它始终从CustomAbpSession OrganizationUnitId返回值,此方法CurrentUnitOfWork.SetFilterParameter未将值设置为filter。

这不仅仅是几行代码。

首先介绍如何在CreateFilterExpression过滤IMayHaveTenant

您可以在DbContext覆盖ShouldFilterEntityCreateFilterExpression

SetTenantId用于配置tenantId,如何从UnitOfWork配置OrganizationUnitId

您可以使用等效的SetFilterParameter方法。

但是,它始终从CustomAbpSession OrganizationUnitId返回值,此方法CurrentUnitOfWork.SetFilterParameter未将值设置为filter。

CurrentUnitOfWorkProvider.Current ,您可以访问Filters

 protected virtual long? GetCurrentOrganizationUnitIdOrNull() { if (CurrentUnitOfWorkProvider != null && CurrentUnitOfWorkProvider.Current != null) { return CurrentUnitOfWorkProvider.Current .Filters.FirstOrDefault(f => f.FilterName == "MayHaveOrganizationUnit")? .FilterParameters["OrganizationUnitId"] as long?; } return ((ICustomAbpSession)AbpSession).OrganizationUnitId; }