LiteOrm在线文档

Expr JSON 序列化格式

LiteOrm 的 ExprJsonConverter 主要围绕两种 JSON 形状展开:

为了更容易学习,建议按这个顺序阅读:

  1. 先看“核心标记说明”,认识 $ / # / @ / $where 这些基础符号。
  2. 再看“常见表达式对比”,理解属性、值、逻辑表达式和 SQL 片段如何拼接。
  3. 最后看“完整查询示例”,把整条查询链路串起来。

1. 核心标记说明

1.1 简洁模式标记

标记 含义 示例
! 取反(Not) {"!": {"#": "IsActive"}}
# 属性引用(Property) {"#": "Name"}{"#": "u.Name"}
$ 类型/操作符标识符 {"$": "table"}{"$": "=="}
$and 逻辑与 {"$and": [...]}
$or 逻辑或 {"$or": [...]}
@ 变量值 {"@": 42}{"@": "hello"}

1.2 Expr 操作符映射

Expr 比较操作符 JSON 简洁表示
.Contains() contains
.EndsWith() endswith
.In() in
.Like() like
.NotContains() notcontains
.NotEndsWith() notendswith
.NotIn() notin
.NotLike() notlike
.RegexpLike() regexp
.NotRegexpLike() notregexp
.NotStartsWith() notstartswith
.StartsWith() startswith
< <
<= <=
<> !=
= ==
> >
>= >=

1.3 ExprType 类型表格

ExprType 说明 简洁标记 正常模式 $
And 逻辑 AND 表达式组合 $and "and"
Delete 删除片段,表示 DELETE 语句 $delete "delete"
Foreign 外键 EXISTS 表达式 $foreign "foreign"
From From 片段,表示数据源(表或视图) $from "from"
Function 函数调用表达式 {"$":"func","函数名":[...]} "func"
GenericSql 通过委托或注册生成的 SQL 片段 - "sql"
GroupBy 分组片段,表示 GROUP BY 子句 $group "group"
Having Having 片段,表示 HAVING 条件 $having "having"
Lambda Lambda 会被解析为内部表达式 - -
LogicBinary 逻辑二元表达式(比较运算) "$":"==", "$":"!=", "$":">", "$":">=", "$":"<", "$":"<=", "$":"in" "logic"
Not 逻辑 NOT 表达式 ! "not"
Or 逻辑 OR 表达式组合 $or "or"
OrderBy 排序片段,表示 ORDER BY 子句 $orderby "orderby"
OrderByItem ORDER BY 项 - "orderbyitem"
Property 属性(列)引用表达式 # "prop"
Section 分页片段,表示 LIMIT/OFFSET 子句 $section "section"
Select 选择片段,表示 SELECT 查询 $select "select"
SelectItem Select 项,用于 SELECT 列定义 - "selectitem"
Table 表片段,表示单表或子查询引用 $table "table"
TableJoin 表连接片段,表示 JOIN 子句 $join "join"
Unary 一元表达式(如 DISTINCT, -a 等) - "unary"
Update 更新片段,表示 UPDATE 语句 $update "update"
Value 值表达式 @(变量)或直接值(常量) "value"
ValueBinary 值二元表达式(算术或串联) "$":"+","$":"-","$":"*", "$":"/, "$":"%", "$":"||" "bin"
ValueSet 值集合表达式(用于 IN 或 CONCAT) - "set"
Where 筛选片段,表示 WHERE 条件 $where "where"

2. 简洁模式 vs 正常模式对比

阅读下面的示例时,可以先记住一个简单原则:

2.1 属性引用(PropertyExpr)

简洁模式:

{"#": "Name"}
{"#": "u.Name"}

正常模式:

{
  "$": "property",
  "PropertyName": "Name",
  "TableAlias": null
}

2.2 值表达式(ValueExpr)

简洁模式 - IsConst=true(常量值):

42
"hello"

已映射的非基础值类型会使用带类型标记的包装格式,以便反序列化时恢复原始 CLR 类型:

{"$datetime": "2024-01-15T10:30:45Z"}
{"$datetimeoffset": "2024-01-15T10:30:45+08:00"}
{"$timespan": "01:00:00"}
{"$guid": "6f9619ff-8b86-d011-b42d-00c04fc964ff"}
{"$bytes": "AQID/w=="}

简洁模式 - IsConst=false(变量值):

{"@": 42}
{"@": "variableName"}

对于变量值,同样会在 @ 内使用类型包装:

{"@": {"$guid": "6f9619ff-8b86-d011-b42d-00c04fc964ff"}}
{"@": {"$bytes": "AQID/w=="}}

正常模式 - IsConst=true(常量值):

{
  "$": "value",
  "Value": 42,
  "IsConst": true
}

正常模式 - IsConst=false(变量值):

{
  "$": "value",
  "Value": 42,
  "IsConst": false
}

当前仅对以下已映射运行时类型使用类型包装:

2.3 逻辑二元表达式(LogicBinaryExpr)

简洁模式:

{
  "$": "==",
  "Left": {"#": "Age"},
  "Right": {"@": 18}
}

正常模式:

{
  "$": "logic",
  "Operator": 0,
  "Left": {
    "$": "property",
    "PropertyName": "Age",
    "TableAlias": null
  },
  "Right": {
    "$": "value",
    "Value": 18,
    "IsConst": false
  }
}

2.4 AND 表达式(AndExpr)

简洁模式:

{
  "$and": [
    {"$": "==", "Left": {"#": "Status"}, "Right": {"@": "Pending"}},
    {"$": ">=", "Left": {"#": "TotalAmount"}, "Right": {"@": 300}}
  ]
}

正常模式:

{
  "$": "and",
  "Items": [
    {
      "$": "logic",
      "Operator": 0,
      "Left": {"$": "property", "PropertyName": "Status"},
      "Right": {"$": "value", "Value": "Pending", "IsConst": false}
    },
    {
      "$": "logic",
      "Operator": 3,
      "Left": {"$": "property", "PropertyName": "TotalAmount"},
      "Right": {"$": "value", "Value": 300, "IsConst": false}
    }
  ]
}

2.5 NOT 表达式(NotExpr)

简洁模式:

{
  "!": {"$": "==", "Left": {"#": "IsActive"}, "Right": {"@": false}}
}

正常模式:

{
  "$": "not",
  "Operand": {
    "$": "logic",
    "Operator": 0,
    "Left": {"$": "property", "PropertyName": "IsActive"},
    "Right": {"$": "value", "Value": false, "IsConst": false}
  }
}

2.6 SQL 片段(SqlSegment)

这类表达式最容易看花,因为它们通常会一层层把 From -> Where -> OrderBy -> Section 串起来。阅读时建议先看最外层标记,再看其 Source 或同层属性。

简洁模式 - TableExpr:

{"$table": "LiteOrm.Tests.Models.TestUser"}

简洁模式 - TableExpr 带参数:

{
  "$table": "LiteOrm.Tests.Models.TestUser",
  "TableArgs": ["2024", "01"],
  "Alias": "u"
}

正常模式 - TableExpr:

{
  "$": "table",
  "Type": "LiteOrm.Tests.Models.TestUser",
  "TableArgs": ["2024", "01"],
  "Alias": "u"
}

说明: FromExpr 的简洁模式使用 $from 作为标记,内部直接包含 TableExpr$table)和 Joins

简洁模式 - FromExpr:

{
  "$from": {
    "$table": "LiteOrm.Tests.Models.TestUser",
    "TableArgs": ["2024", "01"],
    "Alias": "u"
  },
  "Joins": []
}

正常模式 - FromExpr:

{
  "$": "from",
  "Source": {
    "$": "table",
    "Type": "LiteOrm.Tests.Models.TestUser",
    "TableArgs": ["2024", "01"],
    "Alias": "u"
  },
  "Joins": []
}

2.7 WHERE 表达式(WhereExpr)

简洁模式:

{
  "$where": {"$from": {"$table": "LiteOrm.Tests.Models.TestUser"}},
  "Where": {
    "$and": [
      {"$": "==", "Left": {"#": "Status"}, "Right": {"@": "Pending"}},
      {"$": ">=", "Left": {"#": "TotalAmount"}, "Right": {"@": 300}}
    ]
  }
}

正常模式:

{
  "$": "where",
  "Source": {
    "$": "from",
    "Source": {
      "$": "table",
      "Type": "LiteOrm.Tests.Models.TestUser"
    }
  },
  "Where": {
    "$": "and",
    "Items": [
      {"$": "logic", "Operator": 0, "Left": {"#": "Status"}, "Right": {"@": "Pending"}},
      {"$": "logic", "Operator": 3, "Left": {"#": "TotalAmount"}, "Right": {"@": 300}}
    ]
  }
}

2.8 ORDER BY 表达式(OrderByExpr)

简洁模式:

{
  "$orderby": {
    "$where": {"$from": {"$table": "LiteOrm.Tests.Models.TestUser"}}
  },
  "OrderBys": [
    {"Field": {"#": "TotalAmount"}, "Asc": false},
    {"Field": {"#": "CreatedTime"}, "Asc": false}
  ]
}

正常模式:

{
  "$": "orderby",
  "Source": {...},
  "OrderBys": [
    {
      "$": "orderbyitem",
      "Field": {"$": "property", "PropertyName": "TotalAmount"},
      "Asc": false
    },
    {
      "$": "orderbyitem",
      "Field": {"$": "property", "PropertyName": "CreatedTime"},
      "Asc": false
    }
  ]
}

2.9 分页表达式(SectionExpr)

简洁模式:

{
  "$section": {
    "$orderby": {...},
    "OrderBys": [
      {"Field": {"#": "CreatedTime"}, "Asc": false}
    ]
  },
  "Skip": 0,
  "Take": 10
}

3. 完整查询示例

简洁模式

{
  "$section": {
    "$orderby": {
      "$where": {"$from": {"$table": "LiteOrm.Tests.Models.TestUser"}},
      "Where": {
        "$and": [
          {"$": "==", "Left": {"#": "Status"}, "Right": {"@": "Pending"}},
          {"$": ">=", "Left": {"#": "TotalAmount"}, "Right": {"@": 300}},
          {"$": "contains", "Left": {"#": "DepartmentName"}, "Right": {"@": "Operations"}}
        ]
      },
      "OrderBys": [
        {"Field": {"#": "TotalAmount"}, "Asc": false},
        {"Field": {"#": "CreatedTime"}, "Asc": false}
      ]
    }
  },
  "Skip": 0,
  "Take": 5
}

正常模式

{
  "$": "section",
  "Source": {
    "$": "orderby",
    "Source": {
      "$": "where",
      "Source": {
        "$": "from",
        "Source": {
          "$": "table",
          "Type": "LiteOrm.Tests.Models.Order"
        }
      },
      "Where": {
        "$": "and",
        "Items": [
          {
            "$": "logic",
            "Operator": 0,
            "Left": {"$": "property", "PropertyName": "Status"},
            "Right": {"$": "value", "Value": "Pending", "IsConst": false}
          },
          {
            "$": "logic",
            "Operator": 3,
            "Left": {"$": "property", "PropertyName": "TotalAmount"},
            "Right": {"$": "value", "Value": 300, "IsConst": false}
          },
          {
            "$": "logic",
            "Operator": 11,
            "Left": {"$": "property", "PropertyName": "DepartmentName"},
            "Right": {"$": "value", "Value": "Operations", "IsConst": false}
          }
        ]
      }
    },
    "OrderBys": [
      {
        "$": "orderbyitem",
        "Field": {"$": "property", "PropertyName": "TotalAmount"},
        "Asc": false
      },
      {
        "$": "orderbyitem",
        "Field": {"$": "property", "PropertyName": "CreatedTime"},
        "Asc": false
      }
    ]
  },
  "Skip": 0,
  "Take": 5
}

说明:

4. FunctionExpr 额外说明

FunctionExpr 是这页里最容易写错的一类,因为它的简洁模式不是 $fn,而是直接使用 func 标记,再把函数名作为属性名写出来。

简洁模式

{
  "$": "func",
  "DateDiffDays": [
    {"#": "EndTime"},
    {"#": "StartTime"}
  ]
}

正常模式

{
  "$": "func",
  "FunctionName": "DateDiffDays",
  "Args": [
    {"$": "property", "PropertyName": "EndTime"},
    {"$": "property", "PropertyName": "StartTime"}
  ]
}

阅读提示

相关链接