【问题标题】:How to implement Entity Framework Core data filters?如何实现 Entity Framework Core 数据过滤器?
【发布时间】:2018-10-04 18:17:01
【问题描述】:

在我的 ASP.NET Zero 应用程序中,我想通过 CompanyId 值设置数据过滤器。 所以我阅读了here 的文档以及此支持论坛上提供的信息thread

在我的 EF Core 项目中,我进行了以下更改。

public override void PreInitialize()
{
    if (!SkipDbContextRegistration)
    {
        // ...

        Configuration.UnitOfWork.RegisterFilter("CompanyFilter", false);
    }
}

然后我遵循用于IMustHaveTenant 数据过滤器的模式并将以下更改应用到我的数据库上下文类中:

protected int? CurrentCompanyId = null;
protected bool IsCompanyFilterEnabled => CurrentCompanyId != null && CurrentUnitOfWorkProvider?.Current?.IsFilterEnabled("CompanyFilter") == true;    

protected override bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType)
{
    if (typeof(IHasCompany).IsAssignableFrom(typeof(TEntity)))
    {
        return true;
    }
    return false;
}

protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
{
    Expression<Func<TEntity, bool>> expression = null;

    if (typeof(IHasCompany).IsAssignableFrom(typeof(TEntity)))
    {
        Expression<Func<TEntity, bool>> companyFilter = e => ((IHasCompany)e).CompanyId == CurrentCompanyId || (((IHasCompany)e).CompanyId == CurrentCompanyId) == IsCompanyFilterEnabled;
        expression = expression == null ? companyFilter : CombineExpressions(expression, companyFilter);
    }
    return base.CreateFilterExpression<TEntity>();
}

然后,在我希望应用过滤器的应用服务方法中,我添加了以下代码。

public async Task<PagedResultDto<EmployeeListDto>> GetEmployees(GetEmployeeInput input)
{
    using (CurrentUnitOfWork.EnableFilter("CompanyFilter"))
    {
        using (CurrentUnitOfWork.SetFilterParameter("CompanyFilter", "CompanyId", GetCurrentUserCompany()))
        {
            // ...
        }
    }
}

在 DB 上下文类中,如果我在下一行硬编码CompanyId 值,则过滤器工作正常

protected int? CurrentCompanyId = 123;

老实说,我并不完全理解 DB 上下文类中 CreateFilterExpression 方法中使用的代码。我直接从 IMustHaveTenant 过滤器的 ABP GitHub 存储库代码中借用了这个。

我已修改 ABP 用户“我的设置”模式以包含 CompanyId。这允许将每个用户分配给一个公司,因此应用程序应限制该用户的所有公司数据。

在我的应用服务基类中,我有一个名为GetCurrentUserCompany 的方法。此方法获取当前用户的默认公司。这是应在公司数据过滤器上使用的值。

问题:

  • 是否需要在 DB 上下文类中设置此公司值?
  • 如果是,那么如何调用应用服务或存储库方法来获取此 DB 上下文类中的 CompanyId

更新: 我添加了 Aaron 建议的代码,但它仍然无法正常工作。我正在使用分配了公司 1 的用户 ID 进行测试。然而,当数据加载时,它仍然向他们显示公司 1 和 2。

当第 77 行执行并对存储库执行 GetAll 调用时,它仍然向用户显示所有公司。

10 月 6 日更新: 新代码有效,但仅当用户分配了公司 ID 时。当用户没有分配公司时,会抛出下图所示的错误。

【问题讨论】:

    标签: c# asp.net-core filter entity-framework-core aspnetboilerplate


    【解决方案1】:
    • 是否需要在 Db 上下文类中设置此公司值?
    • 如果是,那么如何调用应用服务或存储库方法来获取此 DB 上下文类中的公司 ID?

    没有。在你的 DbContext 类中实现一个 getter:

    // using Abp.Collections.Extensions;
    
    // protected int? CurrentCompanyId = null;
    protected int? CurrentCompanyId => GetCurrentCompanyIdOrNull();
    
    protected virtual int? GetCurrentCompanyIdOrNull()
    {
        if (CurrentUnitOfWorkProvider != null &&
            CurrentUnitOfWorkProvider.Current != null)
        {
            return CurrentUnitOfWorkProvider.Current
                .Filters.FirstOrDefault(f => f.FilterName == "CompanyFilter")?
                .FilterParameters.GetOrDefault("CompanyId") as int?;
        }
    
        return null;
    }
    

    在您的 CreateFilterExpression 方法中返回 expression

    protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
    {
        // Expression<Func<TEntity, bool>> expression = null;
        var expression = base.CreateFilterExpression<TEntity>();
    
        if (typeof(IHasCompany).IsAssignableFrom(typeof(TEntity)))
        {
            Expression<Func<TEntity, bool>> companyFilter = e => ((IHasCompany)e).CompanyId == CurrentCompanyId || (((IHasCompany)e).CompanyId == CurrentCompanyId) == IsCompanyFilterEnabled;
            expression = expression == null ? companyFilter : CombineExpressions(expression, companyFilter);
        }
    
        // return base.CreateFilterExpression<TEntity>();
        return expression;
    }
    

    类似问题:Implement OrganizationUnit filter in ASP.NET Core

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多