在 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 Core 中自定义 Filter
,与 EF 6.x 不同.
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.
这是我目前所做的:
覆盖
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.
推荐答案
这不仅仅是几行代码.
从 IMayHaveTenant
在CreateFilterExpression
.
您可以覆盖DbContext 中的 >ShouldFilterEntity 和 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屋!