在ASP.NET Boilerplate中,有内置的数据过滤器(如“租户”过滤器),我们可以使用SetTenantId启用查询特定的tenantId

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

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

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


覆盖CreateFilterExpression

protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
{
    Expression<Func<TEntity, bool>> expression = null;
    if (typeof(IMayHaveOrganizationUnit).IsAssignableFrom(typeof(TEntity)))
    {
        Expression<Func<TEntity, bool>> mayHaveOUFilter = e => ((IMayHaveOrganizationUnit)e).OrganizationUnitId == CurrentOrganizationUnitId || (((IMayHaveOrganizationUnit)e).OrganizationUnitId == CurrentOrganizationUnitId) == IsMayHaveOrganizationUnitFilterEnabled;
        expression = expression == null ? mayHaveOUFilter : CombineExpressions(expression, mayHaveOUFilter);
    }

    expression = expression == null ? base.CreateFilterExpression<TEntity>() : CombineExpressions(expression, base.CreateFilterExpression<TEntity>());

    return expression;
}

我通过以下代码注册新过滤器:

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



但是,如何实现设置OrganizationUnitId的代码?

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


我尝试如下继承ClaimsAbpSession

public class CustomAbpSession : ClaimsAbpSession, ICustomAbpSession
{
    private readonly IRepository<User, long> _userRepository;

    public CustomAbpSession(
        IRepository<User, long> userRepository,
        IPrincipalAccessor principalAccessor,
        IMultiTenancyConfig multiTenancy,
        ITenantResolver tenantResolver,
        IAmbientScopeProvider<SessionOverride> 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;
}

使用下面的代码注册自定义IAbpSession

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



用法:

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


但是,它总是从OrganizationUnitId中的CustomAbpSession返回值,此方法CurrentUnitOfWork.SetFilterParameter并未将值设置为过滤器。

最佳答案

这不仅仅是几行代码。

从如何在IMayHaveTenant中过滤CreateFilterExpression开始。

您可以在ShouldFilterEntity中覆盖CreateFilterExpressionDbContext


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


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


  但是,它总是从OrganizationUnitId中的CustomAbpSession返回值,此方法CurrentUnitOfWork.SetFilterParameter并未将值设置为过滤器。


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;
}

关于c# - 在ASP.NET Core中实现OrganizationUnit筛选器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49956072/

10-13 02:39