我正在嘗試使用啟用禁用條件實作 ef 核心全域查詢過濾器。根據我的場景,我有一個名為“ FilterStatus ”的標志,它的值會隨著每個用戶的變化而變化。因此,任何登錄到系統FilterStatus值的用戶都會更改。我想實作一個全域查詢過濾器來根據FilterStatus標志過濾資料。
我想出了以下但不適用于全域查詢過濾器的 if-else 陳述句:
public partial class TableDbContext : DbContext, IDbContext
{
protected Guid TenantId { get; set; }
protected UserClaimFilter UserClaimFilter { get; set; } = new UserClaimFilter();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var tenant = _httpContextAccessor?.HttpContext?.GetTenant();
if (tenant != null)
{
TenantId = Guid.Parse(tenant.Id);
var userClaims =
_httpContextAccessor.HttpContext.Session.GetObject<UserClaimFilter>
(DefaultConstants
.SessionUserClaimStore);
if (userClaims != null)
{
UserClaimFilter = userClaims;
}
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Region>(entity =>
{
if (UserClaimFilter.FilterStatus && UserClaimFilter.RegionClaims.Any())
{
entity.HasQueryFilter(a => a.TenantId == TenantId &&
UserClaimFilter.RegionClaims.Contains(a.RegionCode));
}
else
{
entity.HasQueryFilter(a => a.TenantId == TenantId);
}
});
}
}
在上面的代碼中,即使UserClaimFilter.FilterStatus為真,也總是運行 else 部分。我認為由于第一次運行 OnModelCreating UserClaimFilter.FilterStatus 的默認值為false。
根據配置值啟用-禁用全域查詢過濾器的任何解決方案?
uj5u.com熱心網友回復:
全域查詢過濾條件的所有動態部分必須 (1) 源自DbContext成員(與您的代碼一樣)并且 (2) 是運算式的一部分,而不是在構建運算式時評估一次。EF Core 具有在翻譯查詢時消除條件運算式的常量 true 或 false 部分的機制,因此您只需將它們包含在運算式中即可。例如
entity.HasQueryFilter(a => a.TenantId == TenantId &&
(!UserClaimFilter.FilterStatus ||
!UserClaimFilter.RegionClaims.Any() ||
UserClaimFilter.RegionClaims.Contains(a.RegionCode))
);
將過濾器應用于查詢時,如果!UserClaimFilter.FilterStatus或!UserClaimFilter.RegionClaims.Any()為真,那么整個運算式(a || b || c)將被視為常量真并從生成的查詢中消除(因為(x && true) == x)。
更新:正如評論中提到的,目前 EF Core 并沒有完全消除整個運算式。a || b被替換為bool具有true或false值的引數。但是當引數c值為.UserClaimFilter.RegionClaims.Contains(a.RegionCode)booltrue
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/426952.html
標籤:C# asp.net 核心 实体框架核心 ef-core-3.1 全局查询过滤器
上一篇:剃刀頁面:如何使用外鍵制作模型
