Skip to main content

查询前动态拼接过滤条件

本文档介绍如何在「查询集合组件」之前放置 C# 脚本组件,通过 context.AndFilter 动态拼接查询过滤条件。

使用场景​

当查询条件无法在「查询集合组件」中预先配置、需要在链路运行时才确定时,例如:

  • 条件取值来自上游组件的计算结果(如:先查配置表,再按其结果过滤目标数据)
  • 需要根据前端传入参数动态决定过滤范围
  • 需要把多个来源的条件组合成复杂的 And / Or 逻辑
  • 需要保留「查询集合组件」的请求条件与默认条件,只在其基础上「追加」条件

实现方式​

流程配置​

context.AndFilter 是在「查询集合组件」执行时才被读取的,因此 C# 脚本组件必须放在查询集合组件之前。

流程说明:

  1. 开始节点 - 流程入口
  2. C# 脚本组件 - 计算并设置 context.AndFilter
  3. 查询集合组件 - 组装条件时把 context.AndFilter 以 And 关系拼入,再执行查询
  4. 结束组件 - 流程结束,返回查询结果

示例代码​

以下示例演示在查询前追加「启用状态且在今日之后创建」的条件:

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Chameleon.Common;
using Chameleon.Common.Context;
using Chameleon.Common.Exceptions;
using Chameleon.Common.Models;
using Chameleon.Database;
using Chameleon.SDK;

public class ChameleonCSharpScript
{
public string Execute(ComponentContext context, ChameleonSDK sdk)
{
// 只查询启用状态、且创建时间在今天之后的数据
context.AndFilter = FilterBuilder.And(
FilterBuilder.Eq("status", "active"),
FilterBuilder.Gte("createdTime", DateTime.Today)
);

return null;
}
}

关键点说明​

1. context.AndFilter 属性​

  • 类型为 DynamicFilter,用于在条件链路上「按需插入」额外的查询条件。
  • 多个条件用 FilterBuilder.And(...) / FilterBuilder.Or(...) 组合,条件与操作符写法见 查询操作符说明。
  • 未被赋值(null)时不产生任何额外条件。

2. 条件拼接顺序​

「查询集合组件」(DbQueryListComponentManager)组装最终条件时,按以下顺序执行:

  1. 若设置了 context.FilterOverride,直接用它覆盖全部条件,后续条件全部失效(AndFilter 不再生效)。
  2. 否则以请求条件 request.Condition 为基础,And 上「默认条件」(基础模式 / 高级模式的默认条件)。
  3. 对合并后的条件执行默认值占位符替换({Env.*} / {Model.*})。
  4. 最后把 context.AndFilter 以 And 关系拼入。
  5. 再依次拼入查询操作权限与 MOU 数据权限过滤。

因此 context.AndFilter 是「追加」到既有条件之上的,不会覆盖请求条件与默认条件。

3. 与 FilterOverride 的区别​

属性与既有条件的关系说明
AndFilter追加(And)保留请求条件与默认条件,再叠加自身
FilterOverride覆盖直接替换全部条件(MOU 除外),AndFilter 随之失效

需要「在默认条件基础上追加」时用 AndFilter;需要「完全自定义查询条件」时用 FilterOverride。

4. 占位符不会在 AndFilter 中生效​

默认值占位符(如 {Env.LoginUserId}、{Model._id})只对「请求条件 + 默认条件」执行替换,而 context.AndFilter 是在其后才拼入的,因此占位符写在 AndFilter 中不会被替换,需要在脚本中直接使用真实值。

扩展示例​

示例1:根据前端请求参数拼接条件​

前端可在请求的 extend 中携带自定义参数,脚本读取后用其构成条件:

public string Execute(ComponentContext context, ChameleonSDK sdk)
{
// 读取前端请求 extend 中的自定义参数
string categoryId = null;
context.Request.Extend?.TryGetValue("categoryId", out categoryId);

if (!string.IsNullOrEmpty(categoryId))
{
context.AndFilter = FilterBuilder.Eq("categoryId", categoryId);
}

return null;
}

示例2:根据上游组件传递的值拼接条件​

上游组件可通过 DicParam 传递字符串值,本组件读取后再拼接条件:

public string Execute(ComponentContext context, ChameleonSDK sdk)
{
if (context.DicParam.TryGetValue("TargetOrgId", out var orgId)
&& !string.IsNullOrEmpty(orgId))
{
context.AndFilter = FilterBuilder.Eq("organization", orgId);
}

return null;
}

示例3:复杂的 And / Or 组合​

public string Execute(ComponentContext context, ChameleonSDK sdk)
{
context.AndFilter = FilterBuilder.And(
FilterBuilder.Eq("status", "active"),
FilterBuilder.Or(
FilterBuilder.Eq("level", "high"),
FilterBuilder.Gte("amount", 10000)
)
);

return null;
}

示例4:追加到已有的 AndFilter​

如果链路中已有组件设置过 AndFilter,应在其基础上追加,而不是直接赋值覆盖:

public string Execute(ComponentContext context, ChameleonSDK sdk)
{
var extra = FilterBuilder.Eq("isDeleted", false);

context.AndFilter = context.AndFilter != null
? FilterBuilder.And(context.AndFilter, extra)
: extra;

return null;
}

注意事项​

  1. 节点顺序:C# 脚本组件必须位于查询集合组件之前,否则查询已执行完毕,AndFilter 不再生效。
  2. 不要与 FilterOverride 同时使用:一旦设置了 FilterOverride,AndFilter 会被忽略。
  3. 占位符:{Env.*} / {Model.*} 占位符在 AndFilter 中不生效,请直接使用真实值。
  4. 适用组件:context.AndFilter 会被查询集合、查询数量、分组聚合查询以及实体数据源查询读取并拼接,其余查询类组件请以各自文档为准。
  5. 数据权限不受影响:AndFilter 只追加业务条件,MOU 数据权限过滤仍会独立拼接。

常见问题​

Q: 为什么设置了 AndFilter 但查询结果没有变化?​

A: 常见原因有两个:一是 C# 脚本组件放在了查询集合组件之后;二是查询集合组件设置了 FilterOverride,覆盖了包括 AndFilter 在内的全部条件。

Q: AndFilter 会覆盖默认条件吗?​

A: 不会。AndFilter 与请求条件、默认条件是 And 关系,只会进一步缩小结果集。

Q: 如何完全接管查询条件?​

A: 使用 context.FilterOverride 直接指定条件(MOU 数据权限过滤除外)。

相关文档​