簡體   English   中英

在 EF Core fds 中使用運行時數據過濾 HasQueryFilter() 中的行

[英]Use Runtime Data to filter Rows in HasQueryFilter() in EF Core fds

在我的應用程序中,有一個名為RecordType的 Enum,所有表都包含一個名為“TypeId”的字段。 當用戶添加一個新的記錄,我設置TypeId根據用戶的typeid的。 通過這種方式,我想將數據加載到每個用戶的類型。

RecordType是:

public enum RecordType
{
    None=0,
    
    Programmers = 1,
    
    Marketer = 3,
    
    Financial = 5,
}

當用戶使用Programmer類型登錄系統時,我必須加載“Programmer”類型的用戶添加的所有數據。

我想使用HasQueryFilter()但據我所知它只適用於靜態字段並且不能使用currentUserId因為它在運行應用程序后是可能的。

我添加了這樣的擴展方法:

public static class QueryFilterExtensions
{
    public static IQueryable<TEntity> FilterByUser<TEntity>(this IQueryable<TEntity> query, ICurrentUserService currentUser) where TEntity : BaseEntity
    {
        if (currentUser.TypeId != Domain.Enums.RecordType.None)
            query = query.Where(e => e.TypeId == currentUser.TypeId);
        return query;
    }
}

通過這種方式,我必須在閱讀的所有部分重新調用這個擴展方法,如下所示。

 return await _dbContext.Groups.OrderBy(x => x.Id)
             .FilterByUser(_currentUser)
                    .ProjectTo<GroupDto>(_mapper.ConfigurationProvider)
                    .PaginatedListAsync(request.PageIndex, request.PageSize);

我想使用HasQueryFilter()但據我所知它只適用於靜態字段並且不能使用 currentUserId 因為它在運行應用程序后是可能的。

實際上這是可能的,但記錄不充分 - 就像Global Query Filters文檔主題示例的提示:

請注意DbContext實例級別字段的使用: _tenantId用於設置當前租戶。 模型級過濾器將使用來自正確上下文實例(即正在執行查詢的實例)的值。

它真正意味着並且應該記錄的是,不是來自參數或不是常量的全局過濾器查詢表達式部分必須以上下文類為,以便是動態的。 或者換句話說,必須源自上下文類的屬性/字段/方法。

例如,如果您的上下文具有屬性

public RecordType CurrentUserTypeId => // coming from injected service or something

然后您可以在全局查詢過濾器中使用,它將為每個上下文動態評估。 你可以在你的上下文類中使用類似的東西來設置它


void SetQueryFilter<TEntity>(ModelBuilder modelBuilder)
    where TEntity : BaseEntity
{
    modelBuilder.Entity<TEntity>().HasQueryFilter(
        e => this.CurrentUserTypeId == RecordType.None || e.TypeId == this.CurrentUserTypeId);
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    // other stuff...
    var setQueryFilterMethod = new Action<ModelBuilder>(SetQueryFilter<MyBaseEntity>)
        .Method.GetGenericMethodDefinition();
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        if (entityType.BaseType == null && typeof(BaseEntity).IsAssignableFrom(entityType.ClrType))
        {
            setQueryFilterMethod
                .MakeGenericMethod(entityType.ClrType)
                .Invoke(this, new object[] { modelBuilder });
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM