过滤条件构建(DynamicFilter 与 FilterBuilder)
DynamicFilter 是 Chameleon 平台通用的动态查询条件模型(定义于 Chameleon.Common.Models,又称"动态过滤条件 / 查询条件 / where 条件"),用于 IChameleonDbContext 的 GetList / GetCount / IsExist 等查询方法。FilterBuilder 是平台提供的静态工厂类(Chameleon.Database 命名空间),用于以代码方式便捷构建 DynamicFilter。
概述
DynamicFilter 是一棵条件树:叶子节点是「字段 + 操作符 + 值」,非叶子节点通过 Logic(And / Or)组合子条件。它同时被以下场景复用:
推荐始终用 FilterBuilder 构建条件,而不是手写 new DynamicFilter { ... },可避免操作符枚举写错。
DynamicFilter 模型属性
| 属性 | 类型 | 含义 | 取值 |
|---|---|---|---|
Field | string | 字段编码 | 一律使用小写;会被转为小写并做 SQL 注入校验 |
Operator | FilterOperator | 操作符 | 见下方操作符表 |
Value | object | 比较值 | 类型随操作符而定 |
ValueType | FilterValueType | 值类型提示 | Default=0 / String=1 / Number=2 / DateTime=3 / Boolean=4 / Guid=5,默认 Default |
Logic | FilterLogic | 子条件逻辑 | And=0 / Or=1 |
Filters | List<DynamicFilter> | 子条件列表 | 与当前节点为 And 关系 |
操作符总表
FilterOperator 枚举与 FilterBuilder 工厂方法的对应关系(取值以后端枚举为准):
| 语义 | FilterBuilder 方法 | FilterOperator | 存储值 | Value 要求 |
|---|---|---|---|---|
| 等于 | Eq(field, value) | Eq | 9 | 任意 |
| 不等于 | Ne(field, value) | Ne | 10 | 任意 |
| 大于 | Gt(field, value) | Gt | 11 | 可比较类型 |
| 大于等于 | Gte(field, value) | Gte | 12 | 可比较类型 |
| 小于 | Lt(field, value) | Lt | 13 | 可比较类型 |
| 小于等于 | Lte(field, value) | Lte | 14 | 可比较类型 |
| 包含(like %v%) | Contains(field, value) | Ct | 1 | 字符串 |
| 不包含 | NotContains(field, value) | Nct | 4 | 字符串 |
| 前缀匹配 | StartsWith(field, value) | Sw | 2 | 字符串 |
| 非前缀匹配 | NotStartsWith(field, value) | Nsw | 5 | 字符串 |
| 后缀匹配 | EndsWith(field, value) | Ew | 3 | 字符串 |
| 非后缀匹配 | NotEndsWith(field, value) | New | 6 | 字符串 |
| 在集合中 | In(field, value) | In | 17 | 逗号分隔字符串或数组 |
| 不在集合中 | NotIn(field, value) | Nin | 18 | 逗号分隔字符串或数组 |
数组包含(PostgreSQL @>) | Act(field, value) | Act | 19 | 必须传 string[] 或 int[],不支持逗号分隔字符串 |
| 取全量安全条件 | FilterBuilder.Empty(静态属性) | Ne | 10 | 等价于 _id != Guid.Empty |
组合方法:
static DynamicFilter And(params DynamicFilter[] filters); // 生成 Logic = And 的父节点
static DynamicFilter Or(params DynamicFilter[] filters); // 生成 Logic = Or 的父节点
使用示例
单条件
var filter = FilterBuilder.Eq("status", "Pending");
var list = await sdk.DbContext.GetListAsync("LeaveApplication", filter);
And 组合多条件
var filter = FilterBuilder.And(
FilterBuilder.Eq("isdeleted", false),
FilterBuilder.Gte("amount", 1000),
FilterBuilder.Contains("orderno", "SO2026")
);
Or 与嵌套组合
// (status = 'Approved' OR status = 'Rejected') AND isdeleted = false
var filter = FilterBuilder.And(
FilterBuilder.Or(
FilterBuilder.Eq("status", "Approved"),
FilterBuilder.Eq("status", "Rejected")
),
FilterBuilder.Eq("isdeleted", false)
);
In 与数组包含
// In:逗号分隔字符串或数组均可
var inFilter = FilterBuilder.In("status", "Pending,Approved");
var inFilter2 = FilterBuilder.In("_id", someGuidArray);
// Act(数组字段包含):必须传数组,传逗号分隔字符串会抛 ArgumentException
var actFilter = FilterBuilder.Act("tags", new[] { "vip", "oversea" });