JsonApiDotNetCore中如何通过关联对象属性实现OrderLine的隐式过滤?
JsonApiDotNetCore中如何通过关联对象属性实现OrderLine的隐式过滤?
嘿,我刚好做过类似的需求,给你捋捋怎么在JsonApiDotNetCore里实现这个基于关联对象属性的隐式过滤:
核心思路就是在OrderLine的资源定义类中,重写OnApplyFilter方法,构建一个针对关联对象Order的CompanyId属性的过滤表达式,再和前端传入的原有过滤条件做逻辑合并(用And关联,保证前端的过滤和我们的隐式过滤同时生效)。
先给你完整的实现代码,结合你的类结构来写:
using JsonApiDotNetCore.Resources; using JsonApiDotNetCore.Queries.Expressions; using JsonApiDotNetCore.Queries; using JsonApiDotNetCore.Services; public class OrderLineResourceDefinition : JsonApiResourceDefinition<OrderLine, Guid> { // 这里替换成你实际用来获取目标CompanyId的服务,比如当前用户上下文、请求参数解析服务等 private readonly ICurrentUserService _currentUserService; public OrderLineResourceDefinition(IResourceGraph resourceGraph, ICurrentUserService currentUserService) : base(resourceGraph) { _currentUserService = currentUserService; } public override FilterExpression? OnApplyFilter(FilterExpression? existingFilter) { // 第一步:获取要用来过滤的CompanyId,对应你说的"some initialization and Db fetching" // 这里模拟从当前用户上下文获取,你可以换成自己的业务逻辑,比如从请求头、数据库查询等 var currentCompanyId = _currentUserService.GetCurrentCompanyId(); if (currentCompanyId == Guid.Empty) { // 处理没有有效CompanyId的情况,比如返回原有过滤条件,或者抛出权限异常 return existingFilter; } // 第二步:构建关联属性的过滤表达式路径(OrderLine -> Order -> CompanyId) var orderRelationship = ResourceGraph.GetResourceType<OrderLine>().GetRelationshipField(nameof(OrderLine.Order)); var companyIdAttribute = ResourceGraph.GetResourceType<Order>().GetAttributeField(nameof(Order.CompanyId)); var orderCompanyIdPath = new ResourceFieldChainExpression(orderRelationship, companyIdAttribute); // 第三步:创建"Order.CompanyId == currentCompanyId"的过滤条件 var companyIdFilter = new ComparisonExpression( orderCompanyIdPath, ComparisonOperator.Equals, new LiteralExpression(currentCompanyId) ); // 第四步:合并原有过滤条件和我们的隐式过滤条件 if (existingFilter != null) { // 如果前端传了过滤条件,就把两个条件用And组合 return new LogicalExpression(existingFilter, LogicalOperator.And, companyIdFilter); } // 如果前端没传过滤条件,直接用我们的隐式过滤条件 return companyIdFilter; } }
再给你划几个关键的注意点:
- 关联路径的构建:
ResourceFieldChainExpression是用来告诉JsonApiDotNetCore我们要过滤的是关联对象上的属性,这里一定要确保OrderLine的Order关联和Order的CompanyId属性都已经正确注册到资源图中(你已经用[HasOne]和[Attr]标注了,这部分没问题)。 - CompanyId的获取:我这里用了
ICurrentUserService作为示例,你可以根据实际业务场景替换,比如从请求头取、从路由参数解析、或者从数据库查询特定值。 - 过滤条件的合并:用
LogicalExpression的And操作符,保证前端的过滤条件和我们的隐式过滤条件同时生效,不会覆盖前端的需求。 - 异常处理:如果获取不到有效CompanyId,你可以根据业务需求返回原有过滤条件,或者抛出403禁止访问的异常,避免数据泄露。
备注:内容来源于stack exchange,提问作者jobis1205
相关产品推荐
相关产品推荐

