在ASP.NET Core中实施OrganizationUnit筛选器 [英] Implement OrganizationUnit filter in ASP.NET Core
问题描述
在ASP.NET Boilerplate中,内置了数据过滤器(如租户"过滤器),我们可以使用SetTenantId
启用对特定tenantId
的查询.
In ASP.NET Boilerplate, there are built-in Data Filters like Tenant filter, and we could use SetTenantId
to enable querying specific tenantId
.
根据官方文档,与EF 6.x不同,它不支持EF Core中的自定义Filter
.
As per the official document, it did not support custom Filter
in EF Core, unlike EF 6.x.
我想知道如何为OrganizationUnitId
参数实现类似的过滤器.
I am wondering how to achieve a similar filter for OrganizationUnitId
parameter.
这是我到目前为止所做的:
This is what I have done so far:
-
覆盖
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;
}
我通过以下代码注册新过滤器:
I register the new filter by code below:
Configuration.UnitOfWork.RegisterFilter("MayHaveOrganizationUnit", true);
但是,如何实现设置OrganizationUnitId
的代码?
But, how can I implement the code to set OrganizationUnitId
?
SetTenantId
用于配置tenantId
,如何从UnitOfWork
配置OrganizationUnitId
?
SetTenantId
is used to configure the tenantId
, how could I configure OrganizationUnitId
from 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();
}
}
但是,它总是从CustomAbpSession
中的OrganizationUnitId
返回值,此方法CurrentUnitOfWork.SetFilterParameter
并未将值设置为过滤器.
But, it always return value from OrganizationUnitId
in CustomAbpSession
, this method CurrentUnitOfWork.SetFilterParameter
did not set the value into filter.
推荐答案
这不仅仅是几行代码.
首先介绍如何在CreateFilterExpression
.
Start with how IMayHaveTenant
is filtered in CreateFilterExpression
.
You can override ShouldFilterEntity
and CreateFilterExpression
in your DbContext
.
SetTenantId
用于配置tenantId,如何从UnitOfWork
配置OrganizationUnitId
?
SetTenantId
is used to configure the tenantId, how could I configureOrganizationUnitId
fromUnitOfWork
?
您可以使用等效的 SetFilterParameter
方法
You can use the equivalent SetFilterParameter
method.
但是,它总是从
CustomAbpSession
中的OrganizationUnitId
返回值,此方法CurrentUnitOfWork.SetFilterParameter
并未将值设置为过滤器.
But, it always return value from
OrganizationUnitId
inCustomAbpSession
, this methodCurrentUnitOfWork.SetFilterParameter
did not set the value into filter.
从CurrentUnitOfWorkProvider.Current
,您可以访问
From CurrentUnitOfWorkProvider.Current
, you can access 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;
}
这篇关于在ASP.NET Core中实施OrganizationUnit筛选器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!