【发布时间】:2019-12-23 12:30:55
【问题描述】:
我需要创建一个全局查询过滤器,只过滤属于某个租户的用户。
但是,将查询过滤器添加到 OnModelCreating 时,我得到了一个堆栈溢出。
我使用 IHttpContextAccessor 从当前登录的用户获取 TenantId。这适用于其他实体,但 ApplicationUser 会产生错误。这可能是循环代码的问题吗?
我的 ApplicationDbContext 如下(为了清楚起见缩写)
public class ApplicationDbContext
: IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
ApplicationUserRole, IdentityUserLogin<string>,
IdentityRoleClaim<string>, IdentityUserToken<string>>
{
private readonly IHttpContextAccessor _contextAccessor;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor contextAccessor)
: base(options)
{
_contextAccessor = contextAccessor;
}
public virtual Guid? CurrentTenantId
{
get
{
return Users.FirstOrDefault(u => u.UserName == _contextAccessor.HttpContext.User.Identity.Name)?.TenantId;
}
}
public virtual string CurrentUserName
{
get
{
return Users.FirstOrDefault(u => u.UserName == _contextAccessor.HttpContext.User.Identity.Name)?.UserName;
}
}
public DbSet<ApplicationUser> ApplicationUser { get; set; }
public DbSet<Tenant> Tenant { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Tenant>().HasQueryFilter(e => e.TenantId == CurrentTenantId);
builder.Entity<ApplicationUser>().HasQueryFilter(e => e.TenantId == CurrentTenantId);
}
}
}
我已将services.AddHttpContextAccessor() 添加到我启动时的 ConfifureServices 部分。
关于如何解决此问题的任何建议?
【问题讨论】:
-
发生了什么事;您初始化 DbContext。在该上下文中,您尝试访问
Users数据集,但要能够读取它,您必须首先初始化 DbContext,因此 .net 将尝试初始化 DbContext 类。现在你已经陷入了infinite loop。因为 DbContext 需要读取用户 Dbset 而用户 dbset 需要一个 DbContext,所以它会尝试创建一个。此问题的解决方案是在 DbContext 类之外采用检索 TenantId 的逻辑。
标签: c# asp.net-core entity-framework-core asp.net-identity asp.net-core-2.1