首页 > 解决方案 > 使用 IOC 时如何在 EF Core 的 DbContext 中忽略查询过滤器

问题描述

我使用 EF Core 和 .NET Core 中的内置 IOC。我添加HasQueryFilterOnModelCreating,但我想QueryFilter根据某些请求忽略它,例如,如果我的角色是管理员,我想忽略它,并且我想在一种方法中对所有请求使用这个忽略。

我在哪里以及如何做到这一点?

protected override void OnModelCreating(ModelBuilder builder)
{
    // it should be placed here, otherwise it will rewrite the following settings!
    base.OnModelCreating(builder);

    builder.Model.GetEntityTypes()
                .Where(entityType => typeof(ITenant).IsAssignableFrom(entityType.ClrType))
                .ToList()
                .ForEach(entityType =>
                {
                    builder.Entity(entityType.ClrType)
                 
                    .HasQueryFilter(ConvertFilterExpression<ITenant>(e => (GetTenantId() == e.TenantId), entityType.ClrType));
                });
}

private static LambdaExpression ConvertFilterExpression<Entity>(Expression<Func<Entity, bool>> filterExpression,
                 Type entityType)
{
    var newParam = Expression.Parameter(entityType);
    var newBody = ReplacingExpressionVisitor.Replace(filterExpression.Parameters.Single(), newParam, filterExpression.Body);

    return Expression.Lambda(newBody, newParam);
}

private Guid GetTenantId()
{
    var tenantId = new Guid();
    var _httpContextAccessor = this.GetService<IHttpContextAccessor>();

    if (_httpContextAccessor.HttpContext != null && _httpContextAccessor.HttpContext.User.Claims.Any(x => x.Type == "TenantId"))
    {
        var tenant = _httpContextAccessor.HttpContext
                                         .User.Claims
                                         .Where(x => x.Type == "TenantId")
                                         .FirstOrDefault().Value;

        return Guid.Parse(tenant);
    }

    return tenant;
}

标签: c#asp.net-coreasp.net-core-3.1ioc-containeref-core-3.1

解决方案


为什么不创建 2 个 DbContext?一个带过滤器,一个不带。

然后在代码中的其他地方,您可以根据 cookie 或令牌或任何使用 Admin DbContext 或 Filtered DbContext 来决定

也许使 Filtered DbContext 继承自 Admin DbContext


推荐阅读