在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
中覆盖CreateFilterExpression
和DbContext
。
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/