@microi.net/cli 5.8.5 → 5.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/LICENSE +21 -21
- package/README.md +71 -71
- package/assets/build-meta.json +6 -6
- package/assets/feature-matrix.json +138 -138
- package/assets/logo.svg +4 -4
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/codex-marketplace.json +20 -20
- package/scripts/mcp-codex-stdio-adapter.js +189 -189
- package/scripts/mcp-trae-windows-launcher.cmd +21 -21
- package/scripts/microi-cli-mcp.js +7 -7
- package/scripts/microi-cli.js +66 -65
- package/scripts/microi-codex-broker.js +450 -450
- package/scripts/microi-codex-router.js +618 -618
- package/scripts/microi-skills.meta.json +384 -384
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +3566 -3566
- package/skills/README.md +287 -287
- package/skills/ai-engine/SKILL.md +269 -265
- package/skills/ai-engine/agents/openai.yaml +4 -4
- package/skills/ai-engine/references/ai-employees.md +48 -48
- package/skills/ai-engine/references/self-hosted-digital-human.md +59 -59
- package/skills/ai-platform-governance/SKILL.md +177 -177
- package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
- package/skills/app-store/SKILL.md +525 -525
- package/skills/app-store/agents/openai.yaml +4 -4
- package/skills/business-blueprint/SKILL.md +193 -193
- package/skills/datasource-engine/SKILL.md +93 -93
- package/skills/datasource-engine/agents/openai.yaml +4 -4
- package/skills/dos-orm/SKILL.md +97 -97
- package/skills/dos-orm/references/api-reference.md +229 -229
- package/skills/email-engine/SKILL.md +81 -81
- package/skills/email-engine/references/v8-email.md +34 -34
- package/skills/job-engine/SKILL.md +176 -176
- package/skills/job-engine/agents/openai.yaml +4 -4
- package/skills/message-notification/SKILL.md +156 -156
- package/skills/message-notification/agents/openai.yaml +5 -5
- package/skills/message-notification/references/contracts.md +102 -102
- package/skills/microi/SKILL.md +14 -14
- package/skills/microi-ai-app-auth.js +652 -652
- package/skills/microi-ai-application/SKILL.md +115 -115
- package/skills/microi-ai-application/agents/openai.yaml +4 -4
- package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
- package/skills/microi-client-frontend/SKILL.md +244 -244
- package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +144 -144
- package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +196 -196
- package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +167 -167
- package/skills/microi-codex/SKILL.md +102 -102
- package/skills/microi-codex-installer/SKILL.md +231 -231
- package/skills/microi-codex-installer/agents/openai.yaml +7 -7
- package/skills/microi-datasource-mapping/SKILL.md +122 -122
- package/skills/microi-db-schema/SKILL.md +175 -175
- package/skills/microi-db-schema/agents/openai.yaml +4 -4
- package/skills/microi-db-schema/references/core-tables.md +695 -695
- package/skills/microi-db-schema/references/form-component-options.md +256 -256
- package/skills/microi-db-schema/references/schema-overview.md +202 -202
- package/skills/microi-db-schema/references/schema.md +646 -646
- package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
- package/skills/microi-deployment/SKILL.md +221 -221
- package/skills/microi-deployment/references/deployment-matrix.md +109 -109
- package/skills/microi-docs-coverage/SKILL.md +133 -133
- package/skills/microi-docs-coverage/references/capability-map.md +91 -91
- package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
- package/skills/microi-form-engine/SKILL.md +333 -333
- package/skills/microi-form-engine/references/component-catalog.md +218 -218
- package/skills/microi-form-engine/references/data-source-events.md +124 -124
- package/skills/microi-form-layout/SKILL.md +205 -205
- package/skills/microi-form-layout/references/progressive-01-3-/344/270/211/347/247/215/345/210/206/347/273/204/347/232/204/345/255/230/345/202/250/344/270/216/351/205/215/347/275/256.md +235 -235
- package/skills/microi-frontend-sdk/SKILL.md +194 -194
- package/skills/microi-frontend-sdk/references/progressive-01-token-/345/275/223/345/211/215/347/231/273/345/275/225/347/224/250/346/210/267/344/270/216/345/275/223/345/211/215/347/273/210/347/253/257/347/231/273/345/275/225/345/215/217/350/256/256.md +176 -176
- package/skills/microi-left-right-layout/SKILL.md +141 -141
- package/skills/microi-microservice/SKILL.md +326 -324
- package/skills/microi-microservice/references/runtime-delivery.md +278 -278
- package/skills/microi-mobile-app-quality/SKILL.md +185 -185
- package/skills/microi-mobile-app-quality/references/progressive-01-4-/351/207/215/350/246/201/346/214/211/351/222/256/345/277/205/351/241/273/345/270/246/345/233/276/346/240/207.md +213 -213
- package/skills/microi-mobile-app-quality/references/progressive-02-9-/344/270/273/351/242/230/345/210/207/346/215/242/345/277/205/351/241/273/347/234/237/345/256/236/344/270/224/345/205/250/345/261/200/347/224/237/346/225/210.md +128 -128
- package/skills/microi-solution-quotation/SKILL.md +78 -78
- package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
- package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
- package/skills/microi-sso/SKILL.md +92 -92
- package/skills/microi-sso/references/acceptance.md +49 -49
- package/skills/microi-sso/references/configuration-and-security.md +53 -53
- package/skills/microi-sso/references/inbound.md +53 -53
- package/skills/microi-sso/references/outbound.md +39 -39
- package/skills/microi-system-delivery/SKILL.md +137 -137
- package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +193 -193
- package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +217 -217
- package/skills/microi-ui/SKILL.md +192 -192
- package/skills/microi-ui/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/234/272/346/231/257/350/223/235/345/233/276.md +183 -183
- package/skills/microi-uniapp-frontend/SKILL.md +193 -193
- package/skills/microi-uniapp-frontend/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/210/206/347/261/273-/345/217/214/346/240/217/345/210/227/350/241/250/347/213/254/347/253/213/346/273/232/345/212/250.md +225 -225
- package/skills/microi-uniapp-frontend/references/progressive-02-/345/205/263/351/224/256/344/270/232/345/212/241/350/265/204/344/272/247/344/270/215/345/276/227/351/273/230/350/256/244/351/200/211/344/270/255.md +154 -154
- package/skills/microi.v8.js +1921 -1921
- package/skills/module-engine/SKILL.md +255 -255
- package/skills/module-engine/references/module-config.md +204 -204
- package/skills/ocr-engine/SKILL.md +113 -113
- package/skills/ocr-engine/agents/openai.yaml +4 -4
- package/skills/page-engine/SKILL.md +206 -206
- package/skills/page-engine/examples/compact-dashboard.json +1444 -1444
- package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +234 -234
- package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +60 -60
- package/skills/performance-testing/SKILL.md +221 -221
- package/skills/playwright-e2e/SKILL.md +196 -196
- package/skills/playwright-e2e/references/progressive-01-/345/205/250/350/207/252/345/212/250/347/231/273/345/275/225-/345/205/215/351/252/214/350/257/201/347/240/201-/344/275/206/344/270/215/345/205/215/345/257/206/347/240/201-/345/277/205/350/257/273.md +173 -173
- package/skills/playwright-e2e/references/progressive-02-/346/226/207/345/255/227/345/257/271/346/257/224/345/272/246/344/270/216/345/217/257/350/257/273/346/200/247/350/207/252/345/212/250/345/214/226/346/243/200/346/237/245-/345/277/205/345/201/232.md +183 -183
- package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -221
- package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +115 -115
- package/skills/print-engine/SKILL.md +259 -259
- package/skills/production-readonly-audit/SKILL.md +41 -41
- package/skills/report-engine/SKILL.md +71 -71
- package/skills/report-engine/agents/openai.yaml +4 -4
- package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
- package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
- package/skills/scripts/sync-embedded-skills.mjs +46 -46
- package/skills/scripts/validate-progressive-disclosure.mjs +57 -57
- package/skills/search-engine/SKILL.md +75 -75
- package/skills/search-engine/agents/openai.yaml +4 -4
- package/skills/spider-engine/SKILL.md +190 -190
- package/skills/system-observability/SKILL.md +248 -248
- package/skills/system-observability/references/memory-incident-triage.md +77 -77
- package/skills/translate-engine/SKILL.md +140 -140
- package/skills/translate-engine/agents/openai.yaml +4 -4
- package/skills/ui-design/SKILL.md +223 -223
- package/skills/ui-design/assets/pattern-showcase/app.js +54 -54
- package/skills/ui-design/assets/pattern-showcase/index.html +163 -163
- package/skills/ui-design/assets/pattern-showcase/styles.css +311 -311
- package/skills/ui-design/assets/templates/MCI-DESIGN.md +206 -206
- package/skills/ui-design/references/design-pattern-library.md +184 -184
- package/skills/ui-design/references/mci-design-contract.md +163 -163
- package/skills/ui-design/references/motion-and-media.md +78 -78
- package/skills/ui-design/references/product-flow-recipes.md +94 -94
- package/skills/ui-design/references/progressive-01-/351/242/234/350/211/262/344/275/223/347/263/273-css-variables-/346/224/257/346/214/201/344/270/273/351/242/230/345/210/207/346/215/242.md +218 -218
- package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +164 -164
- package/skills/ui-design/references/progressive-03-/345/212/250/346/225/210/350/247/204/350/214/203-/344/270/260/345/257/214/344/275/206/344/270/215/345/215/241.md +235 -235
- package/skills/ui-design/references/progressive-04-/347/273/204/344/273/266/351/243/216/346/240/274/351/200/237/346/237/245.md +152 -152
- package/skills/ui-design/references/progressive-05-/347/247/273/345/212/250/347/253/257/344/270/223/347/224/250/350/247/204/350/214/203.md +238 -238
- package/skills/ui-design/references/progressive-06-/344/270/273/351/242/230/345/210/207/346/215/242/345/256/236/347/216/260.md +194 -194
- package/skills/ui-design/references/progressive-07-/351/200/237/346/237/245-/344/273/216/345/244/264/346/220/255/345/273/272/344/270/200/344/270/252/347/247/273/345/212/250/347/253/257/351/241/265/351/235/242.md +207 -207
- package/skills/ui-design/references/progressive-08-/350/241/250/345/215/225/345/210/206/347/273/204/350/247/204/350/214/203-tabs-vs-collapsegroup-/345/274/272/345/210/266.md +142 -142
- package/skills/uniapp-mall-assets/SKILL.md +176 -176
- package/skills/unity-integration/SKILL.md +171 -171
- package/skills/unity-integration/agents/openai.yaml +4 -4
- package/skills/unity-integration/references/ai-app-delivery.md +119 -119
- package/skills/unity-integration/references/sdk-api.md +82 -82
- package/skills/unity-integration/references/toolbox-migration.md +66 -66
- package/skills/unity-integration/references/webgl-hosting.md +57 -57
- package/skills/v8-api-config/SKILL.md +388 -388
- package/skills/v8-cache-pattern/SKILL.md +312 -312
- package/skills/v8-crud-api/SKILL.md +178 -178
- package/skills/v8-crud-api/references/progressive-01-/346/237/245/350/257/242/345/210/227/350/241/250-/345/210/206/351/241/265.md +226 -226
- package/skills/v8-crud-api/references/progressive-02-where-/346/235/241/344/273/266/350/257/255/346/263/225/351/200/237/346/237/245.md +49 -49
- package/skills/v8-debugging/SKILL.md +284 -284
- package/skills/v8-explorer-tree/SKILL.md +228 -228
- package/skills/v8-export-import/SKILL.md +219 -219
- package/skills/v8-export-import/references/progressive-01-excellayout-/351/253/230/347/272/247/350/207/252/347/224/261/345/270/203/345/261/200.md +211 -211
- package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -202
- package/skills/v8-export-import/references/progressive-03-/345/256/211/345/205/250-/346/200/247/350/203/275/346/263/250/346/204/217.md +42 -42
- package/skills/v8-file-upload/SKILL.md +284 -284
- package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +263 -263
- package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +161 -161
- package/skills/v8-formengine-http/SKILL.md +238 -238
- package/skills/v8-frontend-events/SKILL.md +180 -180
- package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
- package/skills/v8-frontend-events/references/bluetooth-print.md +258 -258
- package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -219
- package/skills/v8-http-integration/SKILL.md +182 -182
- package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -220
- package/skills/v8-http-integration/references/progressive-02-/351/224/231/350/257/257/345/244/204/347/220/206/346/250/241/345/274/217.md +44 -44
- package/skills/v8-image-processing/SKILL.md +190 -190
- package/skills/v8-image-processing/agents/openai.yaml +4 -4
- package/skills/v8-image-processing/references/api-reference.md +623 -623
- package/skills/v8-menu-buttons/SKILL.md +186 -186
- package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +222 -222
- package/skills/v8-menu-buttons/references/progressive-02-8-/346/250/241/345/274/217-f-/345/220/216/345/217/260/344/273/273/345/212/241/346/214/211/351/222/256-/351/225/277/344/273/273/345/212/241.md +228 -228
- package/skills/v8-menu-buttons/references/progressive-03-10-/345/217/215/346/250/241/345/274/217-/351/201/277/345/205/215.md +104 -104
- package/skills/v8-mongodb/SKILL.md +200 -200
- package/skills/v8-mq-mqtt/SKILL.md +176 -176
- package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
- package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -181
- package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
- package/skills/v8-saas-multi-tenant/SKILL.md +305 -305
- package/skills/v8-security/SKILL.md +210 -210
- package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +200 -200
- package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +160 -160
- package/skills/v8-sql-query/SKILL.md +302 -302
- package/skills/v8-table-event/SKILL.md +176 -176
- package/skills/v8-table-event/references/progressive-01-informv8-js-/350/241/250/345/215/225/346/211/223/345/274/200/344/272/213/344/273/266.md +216 -216
- package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +46 -46
- package/skills/v8-tcp-integration/SKILL.md +147 -147
- package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
- package/skills/v8-template-engine/SKILL.md +167 -167
- package/skills/v8-utilities/SKILL.md +104 -104
- package/skills/v8-utilities/references/client-api-index.md +143 -143
- package/skills/v8-utilities/references/platform-http-routes.md +83 -83
- package/skills/v8-utilities/references/server-api-index.md +188 -188
- package/skills/v8-workflow/SKILL.md +252 -252
- package/skills/v8-workflow/references/progressive-01-/350/212/202/347/202/271/345/274/200/345/247/213-v8-/344/272/213/344/273/266.md +180 -180
- package/skills/v8-workflow/references/workflow-configuration.md +49 -49
- package/skills/vision-engine/SKILL.md +160 -160
- package/skills/vision-engine/agents/openai.yaml +4 -4
- package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
- package/skills/workspace-conventions/SKILL.md +273 -273
- package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +209 -209
- package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +217 -217
- package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +27 -27
package/skills/dos-orm/SKILL.md
CHANGED
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: dos-orm
|
|
3
|
-
description: Dos.ORM C# 数据访问指南。用于 Microi.Server 中编写或审查 DbSession、Entity、From、WhereClip、事务、异步查询、BulkInsert、Upsert、SqlFunc、子查询、导航属性、CodeFirst、读写分离和分库分表代码。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
7
|
-
|
|
8
|
-
# Dos.ORM
|
|
9
|
-
|
|
10
|
-
Dos.ORM 是 Microi.Server 底层 C# ORM。它不是接口引擎里的 `V8.Db`:
|
|
11
|
-
|
|
12
|
-
- C# 服务端源码使用 `DbSession`、实体和 Section API。
|
|
13
|
-
- V8 JavaScript 使用 `V8.FormEngine` 或 `V8.Db.FromSql`。
|
|
14
|
-
- 不能把 C# lambda/事务示例原样放进 V8。
|
|
15
|
-
|
|
16
|
-
完整 API、跨库行为与示例见 `references/api-reference.md`。
|
|
17
|
-
|
|
18
|
-
## 默认选择
|
|
19
|
-
|
|
20
|
-
| 需求 | 首选 |
|
|
21
|
-
|---|---|
|
|
22
|
-
| 普通实体查询 | `dbSession.From<T>().Where(...).ToList/ToListAsync` |
|
|
23
|
-
| 动态条件 | `Where<T>` / `WhereClip` |
|
|
24
|
-
| 复杂 SQL | `FromSql(...).AddInParameter(...)` |
|
|
25
|
-
| 单条/小批写入 | `Insert/Update/Delete` |
|
|
26
|
-
| 大于约 1000 行批量插入 | `BulkInsert/BulkInsertAsync`,先压测批大小 |
|
|
27
|
-
| 按唯一键写入 | `Upsert/UpsertAsync` + 真实唯一索引 |
|
|
28
|
-
| 多步原子写 | `BeginTransaction()`,`using` + Commit/Rollback |
|
|
29
|
-
|
|
30
|
-
## 安全规则
|
|
31
|
-
|
|
32
|
-
### 连接生命周期与在线恢复
|
|
33
|
-
|
|
34
|
-
- 创建事务、准备读取器、打开连接、提交/回滚及批处理任一路径抛异常,都必须释放本层拥有的连接;借用外部事务或批处理连接时不能擅自关闭。保留原始异常,不因 Dispose 失败遮盖原始错误。
|
|
35
|
-
- `DbTrans` 提交成功后先归还连接,再执行提交后通知。通知失败不能把已提交事务报告为回滚,也不能自动重放业务 SQL。调用者仍必须使用 `using`,防止业务异常绕过 Commit/Rollback。
|
|
36
|
-
- `DatabasePoolExhausted`、`DatabaseCapacityExceeded`、`DatabaseEndpointUnreachable` 是不同故障;不要把应用池等待、数据库全局连接限制和慢 SQL 混为一谈。
|
|
37
|
-
- 可信 C# 宿主通过 `Database.GetConnectionPoolSnapshot()` 读取脱敏状态,`ResetConnectionPool()` 只轮换准确匹配的 MySQL/SQL Server 池,`ProbeConnectionPoolAsync` 用原池执行固定 `SELECT 1`。不使用 `ClearAllPools`,不杀借出的事务,不重放 SQL。
|
|
38
|
-
- `BeginIsolatedConnections()` 仅用于有并发限制的可信应急鉴权作用域,设置无池连接与 5 秒连接/命令超时;未知驱动拒绝。不能给普通业务或 V8 增加绕过限流的开关,不能在此作用域内执行清池或把无池探测冒充原池恢复。
|
|
39
|
-
- AI 在线恢复使用 `microi_manage_system_observability(action=ResetDatabasePools)` 的预览、确认和回读协议,详细决策见 [系统日志/监控](../system-observability/SKILL.md)。需要升级含 `database-pools/v1` 的后端和 MCP;事故恢复本身不要求重启数据库/API。
|
|
40
|
-
|
|
41
|
-
- 数据值全程参数化;`FromSql` 的动态值用 `AddInParameter`。
|
|
42
|
-
- 表名、字段名、排序名不能来自未经白名单验证的用户输入。
|
|
43
|
-
- 保留 `{0}Name{1}` 标识符延迟绑定机制,不能改成字符串替换。
|
|
44
|
-
- `OrderByClip` 的校验不是授权;可排序字段仍需业务白名单。
|
|
45
|
-
- Upsert 幂等依赖数据库唯一键,不能只靠“先查再写”。
|
|
46
|
-
- 租户业务表查询/写入必须包含真实 `OsClient` 范围。
|
|
47
|
-
- 已明确需要的索引在 Microi 业务表上通过 Manifest/MCP 管理,不从临时 SQL 创建。
|
|
48
|
-
- MySQL 用户名或密码包含分号时必须用连接字符串引号包裹,例如
|
|
49
|
-
`Password="a;b"`;平台统一兼容层只修复“无等号片段紧跟已明确凭据参数”的
|
|
50
|
-
历史串,其它结构错误继续失败关闭,禁止猜测用户名、密码或默认 `root`。
|
|
51
|
-
|
|
52
|
-
## 事务与异步
|
|
53
|
-
|
|
54
|
-
```csharp
|
|
55
|
-
using (var trans = dbSession.BeginTransaction())
|
|
56
|
-
{
|
|
57
|
-
try
|
|
58
|
-
{
|
|
59
|
-
trans.Insert(entity);
|
|
60
|
-
trans.Update<User>(User._.Status, 1, User._.Id == entity.Id);
|
|
61
|
-
trans.Commit();
|
|
62
|
-
}
|
|
63
|
-
catch
|
|
64
|
-
{
|
|
65
|
-
trans.Rollback();
|
|
66
|
-
throw;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Dispose 幂等,未 Commit 时自动回滚。事务内异步操作串行执行;不要在同一个连接/
|
|
72
|
-
事务上 `Task.WhenAll`。取消、超时和异常必须传播,不能吞掉后继续 Commit。
|
|
73
|
-
|
|
74
|
-
## 性能与跨库
|
|
75
|
-
|
|
76
|
-
- 显式选择字段,分页和流式读取,避免无界 `ToList()`。
|
|
77
|
-
- BulkInsert 会按可用客户端选择原生实现并回退多行 INSERT;不同数据库必须实测。
|
|
78
|
-
- 官网性能数字仅是特定环境参考,不能作为目标环境承诺。
|
|
79
|
-
- 查询缓存 Key 必须包含 SQL 参数值;业务写后考虑失效。
|
|
80
|
-
- 读写分离在“写后立刻读”和事务内强制读主。
|
|
81
|
-
- 分片使用稳定 Hash;不能使用进程随机化的 `string.GetHashCode()`。
|
|
82
|
-
|
|
83
|
-
## 验收
|
|
84
|
-
|
|
85
|
-
- Oracle 原生 `TO_CHAR(value, format[, nlsparam])` 必须保留参数顺序;Provider 不得用
|
|
86
|
-
字符串扫描交换参数。单参数、嵌套函数、格式串中的逗号、注释与字面量也要原样保留。
|
|
87
|
-
- `ToArray/ToList` 是查询执行与读取边界,堆栈停在这里不能证明对象转换出错。
|
|
88
|
-
遇到 `ORA-01722`,先用同一账号条件拆分计数/列表,核对最终命令文本与参数类型,
|
|
89
|
-
再执行最小原生 SQL 对照;确定性的转换/语法错误不得用盲目重试或更改业务过滤掩盖。
|
|
90
|
-
|
|
91
|
-
- 至少在目标数据库 Provider 运行定向测试,不用 MySQL 结果宣称 Oracle/达梦通过。
|
|
92
|
-
- 覆盖 NULL、DateTime、decimal、Guid、enum、byte[] 和分页边界。
|
|
93
|
-
- FormEngine 的 decimal 字符串绑定固定使用 `InvariantCulture` 且禁用千分组,防止 `de-DE` / `tr-TR` 把 `1.500000` 转成 `1500000`。类型化 CLR 数值保留原值;无效、本地化逗号或越界仍抛字段转换错误。绑定层修复不能恢复上游 JavaScript 浮点丢失的位数,必须保留原十进制字符串并分别验收实际 Provider 往返与 HTTP 提交。
|
|
94
|
-
- 覆盖事务提交/回滚、唯一冲突、超时、取消和连接故障。
|
|
95
|
-
- BulkInsert/Upsert 核对受影响行、Identity 跳过、唯一键和重试副作用。
|
|
96
|
-
- 读写分离覆盖从库故障、写后读主和降级。
|
|
97
|
-
- CodeFirst/索引变更在隔离库验证,不直接对生产执行破坏性重建。
|
|
1
|
+
---
|
|
2
|
+
name: dos-orm
|
|
3
|
+
description: Dos.ORM C# 数据访问指南。用于 Microi.Server 中编写或审查 DbSession、Entity、From、WhereClip、事务、异步查询、BulkInsert、Upsert、SqlFunc、子查询、导航属性、CodeFirst、读写分离和分库分表代码。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
|
|
7
|
+
|
|
8
|
+
# Dos.ORM
|
|
9
|
+
|
|
10
|
+
Dos.ORM 是 Microi.Server 底层 C# ORM。它不是接口引擎里的 `V8.Db`:
|
|
11
|
+
|
|
12
|
+
- C# 服务端源码使用 `DbSession`、实体和 Section API。
|
|
13
|
+
- V8 JavaScript 使用 `V8.FormEngine` 或 `V8.Db.FromSql`。
|
|
14
|
+
- 不能把 C# lambda/事务示例原样放进 V8。
|
|
15
|
+
|
|
16
|
+
完整 API、跨库行为与示例见 `references/api-reference.md`。
|
|
17
|
+
|
|
18
|
+
## 默认选择
|
|
19
|
+
|
|
20
|
+
| 需求 | 首选 |
|
|
21
|
+
|---|---|
|
|
22
|
+
| 普通实体查询 | `dbSession.From<T>().Where(...).ToList/ToListAsync` |
|
|
23
|
+
| 动态条件 | `Where<T>` / `WhereClip` |
|
|
24
|
+
| 复杂 SQL | `FromSql(...).AddInParameter(...)` |
|
|
25
|
+
| 单条/小批写入 | `Insert/Update/Delete` |
|
|
26
|
+
| 大于约 1000 行批量插入 | `BulkInsert/BulkInsertAsync`,先压测批大小 |
|
|
27
|
+
| 按唯一键写入 | `Upsert/UpsertAsync` + 真实唯一索引 |
|
|
28
|
+
| 多步原子写 | `BeginTransaction()`,`using` + Commit/Rollback |
|
|
29
|
+
|
|
30
|
+
## 安全规则
|
|
31
|
+
|
|
32
|
+
### 连接生命周期与在线恢复
|
|
33
|
+
|
|
34
|
+
- 创建事务、准备读取器、打开连接、提交/回滚及批处理任一路径抛异常,都必须释放本层拥有的连接;借用外部事务或批处理连接时不能擅自关闭。保留原始异常,不因 Dispose 失败遮盖原始错误。
|
|
35
|
+
- `DbTrans` 提交成功后先归还连接,再执行提交后通知。通知失败不能把已提交事务报告为回滚,也不能自动重放业务 SQL。调用者仍必须使用 `using`,防止业务异常绕过 Commit/Rollback。
|
|
36
|
+
- `DatabasePoolExhausted`、`DatabaseCapacityExceeded`、`DatabaseEndpointUnreachable` 是不同故障;不要把应用池等待、数据库全局连接限制和慢 SQL 混为一谈。
|
|
37
|
+
- 可信 C# 宿主通过 `Database.GetConnectionPoolSnapshot()` 读取脱敏状态,`ResetConnectionPool()` 只轮换准确匹配的 MySQL/SQL Server 池,`ProbeConnectionPoolAsync` 用原池执行固定 `SELECT 1`。不使用 `ClearAllPools`,不杀借出的事务,不重放 SQL。
|
|
38
|
+
- `BeginIsolatedConnections()` 仅用于有并发限制的可信应急鉴权作用域,设置无池连接与 5 秒连接/命令超时;未知驱动拒绝。不能给普通业务或 V8 增加绕过限流的开关,不能在此作用域内执行清池或把无池探测冒充原池恢复。
|
|
39
|
+
- AI 在线恢复使用 `microi_manage_system_observability(action=ResetDatabasePools)` 的预览、确认和回读协议,详细决策见 [系统日志/监控](../system-observability/SKILL.md)。需要升级含 `database-pools/v1` 的后端和 MCP;事故恢复本身不要求重启数据库/API。
|
|
40
|
+
|
|
41
|
+
- 数据值全程参数化;`FromSql` 的动态值用 `AddInParameter`。
|
|
42
|
+
- 表名、字段名、排序名不能来自未经白名单验证的用户输入。
|
|
43
|
+
- 保留 `{0}Name{1}` 标识符延迟绑定机制,不能改成字符串替换。
|
|
44
|
+
- `OrderByClip` 的校验不是授权;可排序字段仍需业务白名单。
|
|
45
|
+
- Upsert 幂等依赖数据库唯一键,不能只靠“先查再写”。
|
|
46
|
+
- 租户业务表查询/写入必须包含真实 `OsClient` 范围。
|
|
47
|
+
- 已明确需要的索引在 Microi 业务表上通过 Manifest/MCP 管理,不从临时 SQL 创建。
|
|
48
|
+
- MySQL 用户名或密码包含分号时必须用连接字符串引号包裹,例如
|
|
49
|
+
`Password="a;b"`;平台统一兼容层只修复“无等号片段紧跟已明确凭据参数”的
|
|
50
|
+
历史串,其它结构错误继续失败关闭,禁止猜测用户名、密码或默认 `root`。
|
|
51
|
+
|
|
52
|
+
## 事务与异步
|
|
53
|
+
|
|
54
|
+
```csharp
|
|
55
|
+
using (var trans = dbSession.BeginTransaction())
|
|
56
|
+
{
|
|
57
|
+
try
|
|
58
|
+
{
|
|
59
|
+
trans.Insert(entity);
|
|
60
|
+
trans.Update<User>(User._.Status, 1, User._.Id == entity.Id);
|
|
61
|
+
trans.Commit();
|
|
62
|
+
}
|
|
63
|
+
catch
|
|
64
|
+
{
|
|
65
|
+
trans.Rollback();
|
|
66
|
+
throw;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Dispose 幂等,未 Commit 时自动回滚。事务内异步操作串行执行;不要在同一个连接/
|
|
72
|
+
事务上 `Task.WhenAll`。取消、超时和异常必须传播,不能吞掉后继续 Commit。
|
|
73
|
+
|
|
74
|
+
## 性能与跨库
|
|
75
|
+
|
|
76
|
+
- 显式选择字段,分页和流式读取,避免无界 `ToList()`。
|
|
77
|
+
- BulkInsert 会按可用客户端选择原生实现并回退多行 INSERT;不同数据库必须实测。
|
|
78
|
+
- 官网性能数字仅是特定环境参考,不能作为目标环境承诺。
|
|
79
|
+
- 查询缓存 Key 必须包含 SQL 参数值;业务写后考虑失效。
|
|
80
|
+
- 读写分离在“写后立刻读”和事务内强制读主。
|
|
81
|
+
- 分片使用稳定 Hash;不能使用进程随机化的 `string.GetHashCode()`。
|
|
82
|
+
|
|
83
|
+
## 验收
|
|
84
|
+
|
|
85
|
+
- Oracle 原生 `TO_CHAR(value, format[, nlsparam])` 必须保留参数顺序;Provider 不得用
|
|
86
|
+
字符串扫描交换参数。单参数、嵌套函数、格式串中的逗号、注释与字面量也要原样保留。
|
|
87
|
+
- `ToArray/ToList` 是查询执行与读取边界,堆栈停在这里不能证明对象转换出错。
|
|
88
|
+
遇到 `ORA-01722`,先用同一账号条件拆分计数/列表,核对最终命令文本与参数类型,
|
|
89
|
+
再执行最小原生 SQL 对照;确定性的转换/语法错误不得用盲目重试或更改业务过滤掩盖。
|
|
90
|
+
|
|
91
|
+
- 至少在目标数据库 Provider 运行定向测试,不用 MySQL 结果宣称 Oracle/达梦通过。
|
|
92
|
+
- 覆盖 NULL、DateTime、decimal、Guid、enum、byte[] 和分页边界。
|
|
93
|
+
- FormEngine 的 decimal 字符串绑定固定使用 `InvariantCulture` 且禁用千分组,防止 `de-DE` / `tr-TR` 把 `1.500000` 转成 `1500000`。类型化 CLR 数值保留原值;无效、本地化逗号或越界仍抛字段转换错误。绑定层修复不能恢复上游 JavaScript 浮点丢失的位数,必须保留原十进制字符串并分别验收实际 Provider 往返与 HTTP 提交。
|
|
94
|
+
- 覆盖事务提交/回滚、唯一冲突、超时、取消和连接故障。
|
|
95
|
+
- BulkInsert/Upsert 核对受影响行、Identity 跳过、唯一键和重试副作用。
|
|
96
|
+
- 读写分离覆盖从库故障、写后读主和降级。
|
|
97
|
+
- CodeFirst/索引变更在隔离库验证,不直接对生产执行破坏性重建。
|
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
# Dos.ORM API 参考
|
|
2
|
-
|
|
3
|
-
## 数据库 Provider
|
|
4
|
-
|
|
5
|
-
| DatabaseType | Provider |
|
|
6
|
-
|---|---|
|
|
7
|
-
| `SqlServer` | SQL Server 2000 |
|
|
8
|
-
| `SqlServer9` | SQL Server 2005+ |
|
|
9
|
-
| `MySql` | MySQL |
|
|
10
|
-
| `Oracle` | Oracle |
|
|
11
|
-
| `PostgreSql` | PostgreSQL |
|
|
12
|
-
| `DaMeng` | 达梦 |
|
|
13
|
-
| `KingBase` | 人大金仓 |
|
|
14
|
-
| `Sqlite3` | SQLite |
|
|
15
|
-
| `MsAccess` | Access |
|
|
16
|
-
|
|
17
|
-
兼容协议数据库仍需目标库实测,不能只凭协议名称判定所有 DDL、分页和 BulkCopy 一致。
|
|
18
|
-
|
|
19
|
-
默认会话入口是 `DbSession.Default`;多数据库、读写分离和分片场景使用明确的
|
|
20
|
-
`DbSession` 实例,避免把默认连接误用于其它租户或数据库。
|
|
21
|
-
|
|
22
|
-
## 实体
|
|
23
|
-
|
|
24
|
-
```csharp
|
|
25
|
-
[TableName("sys_user")]
|
|
26
|
-
public class SysUser : Entity
|
|
27
|
-
{
|
|
28
|
-
public string Id { get; set; }
|
|
29
|
-
public string Account { get; set; }
|
|
30
|
-
public DateTime CreateTime { get; set; }
|
|
31
|
-
|
|
32
|
-
public override Field[] GetFields() => new[] { _.Id, _.Account, _.CreateTime };
|
|
33
|
-
public override object[] GetValues() => new object[] { Id, Account, CreateTime };
|
|
34
|
-
public override Field GetIdentityField() => _.Id;
|
|
35
|
-
|
|
36
|
-
public sealed class _
|
|
37
|
-
{
|
|
38
|
-
public static readonly Field Id = new Field("Id", "sys_user");
|
|
39
|
-
public static readonly Field Account = new Field("Account", "sys_user");
|
|
40
|
-
public static readonly Field CreateTime = new Field("CreateTime", "sys_user");
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
`Entity.GetFields()` 的字段顺序也是批量写入和 CodeFirst 映射依据;实体声明、
|
|
46
|
-
字段数组与数据库列变更必须同步。
|
|
47
|
-
|
|
48
|
-
## 查询链
|
|
49
|
-
|
|
50
|
-
| API | 作用 |
|
|
51
|
-
|---|---|
|
|
52
|
-
| `From<T>()` / `From("table")` | 查询入口 |
|
|
53
|
-
| `Where(predicate)` / `Where(WhereClip)` | 条件 |
|
|
54
|
-
| `OrderBy` / `OrderByDescending` | 排序 |
|
|
55
|
-
| `GroupBy` / `Having` | 分组 |
|
|
56
|
-
| `Select` / `AddSelect` | 选择字段 |
|
|
57
|
-
| `Distinct` / `Top` / `Page` | 去重、Top、分页 |
|
|
58
|
-
| `InnerJoin/LeftJoin/RightJoin/CrossJoin/FullJoin` | Join |
|
|
59
|
-
| `Union/UnionAll` | 集合联合 |
|
|
60
|
-
| `SetCacheTimeOut` / `Refresh` | 查询缓存/绕过缓存 |
|
|
61
|
-
| `ToList/ToListAsync` | 列表 |
|
|
62
|
-
| `ToFirst/ToFirstAsync` | 第一条或 null |
|
|
63
|
-
| `ToFirstDefault` | 第一条或 new 实体 |
|
|
64
|
-
| `ToScalar/ToScalarAsync` | 标量 |
|
|
65
|
-
| `ToDataReader` / `ToDataTable/ToDataTableAsync` | Reader/DataTable |
|
|
66
|
-
| `ToEnumerable` | 流式枚举 |
|
|
67
|
-
| `Count/CountAsync` | 计数 |
|
|
68
|
-
| `ExecuteNonQuery/ExecuteNonQueryAsync` | 非查询 |
|
|
69
|
-
|
|
70
|
-
查询缓存入口的完整成员名是 `FromSection.SetCacheTimeOut`。缓存 Key 包含 SQL
|
|
71
|
-
与参数值,但写后失效、租户隔离和多节点一致性仍由业务负责。
|
|
72
|
-
|
|
73
|
-
```csharp
|
|
74
|
-
var users = await dbSession.From<SysUser>()
|
|
75
|
-
.Where(u => u.Account == account)
|
|
76
|
-
.OrderByDescending(u => u.CreateTime)
|
|
77
|
-
.Page(20, 1)
|
|
78
|
-
.ToListAsync();
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## WhereClip
|
|
82
|
-
|
|
83
|
-
```csharp
|
|
84
|
-
var where = new Where<SysUser>();
|
|
85
|
-
where.And(u => u.Status == 1);
|
|
86
|
-
if (!string.IsNullOrWhiteSpace(keyword))
|
|
87
|
-
where.And(u => u.Name.Like(keyword));
|
|
88
|
-
if (deptIds?.Any() == true)
|
|
89
|
-
where.And(u => u.DeptId.In(deptIds));
|
|
90
|
-
|
|
91
|
-
var list = dbSession.From<SysUser>()
|
|
92
|
-
.Where(where.ToWhereClip())
|
|
93
|
-
.ToList();
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
支持比较、`Like/NotLike/StartsWith/EndsWith`、`In/NotIn` 和 NULL。
|
|
97
|
-
|
|
98
|
-
## 原生 SQL
|
|
99
|
-
|
|
100
|
-
```csharp
|
|
101
|
-
var users = dbSession
|
|
102
|
-
.FromSql("SELECT Id,Account FROM sys_user WHERE Status=@p0")
|
|
103
|
-
.AddInParameter("@p0", 1)
|
|
104
|
-
.ToList<SysUser>();
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
动态值只走参数;动态标识符先从固定白名单映射。
|
|
108
|
-
Provider 的标识符替换最终由 `DataUtils.FormatSQL` 完成;不要绕过该步骤手工
|
|
109
|
-
拼接用户输入的表名或字段名。
|
|
110
|
-
|
|
111
|
-
## 写入
|
|
112
|
-
|
|
113
|
-
```csharp
|
|
114
|
-
dbSession.Insert(entity);
|
|
115
|
-
dbSession.Insert(list);
|
|
116
|
-
dbSession.Update<SysUser>(u => u.Status, 0, u => u.Id == id);
|
|
117
|
-
dbSession.Delete<SysUser>(u => u.Id == id);
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
批量:
|
|
121
|
-
|
|
122
|
-
```csharp
|
|
123
|
-
var affected = dbSession.BulkInsert(list, batchSize: 5000, bulkCopyTimeoutSeconds: 600);
|
|
124
|
-
var affectedAsync = await dbSession.BulkInsertAsync(list, batchSize: 5000, ct: token);
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
原生优选:
|
|
128
|
-
|
|
129
|
-
- SQL Server:SqlBulkCopy
|
|
130
|
-
- MySQL:MySqlBulkCopy
|
|
131
|
-
- PostgreSQL/KingBase:Binary COPY
|
|
132
|
-
- Oracle/达梦/SQLite/Access:多行参数化 INSERT 回退
|
|
133
|
-
|
|
134
|
-
批大小 5000 只是起点;按行宽、索引、日志、网络和数据库负载测量。
|
|
135
|
-
|
|
136
|
-
## Upsert
|
|
137
|
-
|
|
138
|
-
```csharp
|
|
139
|
-
dbSession.Upsert(user, SysUser._.Account);
|
|
140
|
-
await dbSession.UpsertAsync(
|
|
141
|
-
user,
|
|
142
|
-
ct: token,
|
|
143
|
-
conflictFields: new[] { SysUser._.Account });
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
各 Provider 使用 `ON DUPLICATE KEY`、`ON CONFLICT`、`MERGE` 或更新后插入回退。
|
|
147
|
-
冲突字段必须有数据库唯一约束。
|
|
148
|
-
|
|
149
|
-
## SqlFunc 与子查询
|
|
150
|
-
|
|
151
|
-
`SqlFunc` 提供 `SqlFunc.IfNull`、`SqlFunc.IIF`、`SqlFunc.Length`、
|
|
152
|
-
`SqlFunc.Substring`、`SqlFunc.Now`、`SqlFunc.DateDiff`、
|
|
153
|
-
`SqlFunc.JsonValue`、`SqlFunc.Concat`、`SqlFunc.Upper`、`SqlFunc.Lower`、
|
|
154
|
-
`SqlFunc.Trim`、`SqlFunc.Abs`、`SqlFunc.Round`、`SqlFunc.Count`、
|
|
155
|
-
`SqlFunc.Sum`、`SqlFunc.Avg`、`SqlFunc.Min`、`SqlFunc.Max` 的 Provider 方言。
|
|
156
|
-
|
|
157
|
-
`SqlSubQuery` 提供 `SqlSubQuery.Exists`、`SqlSubQuery.NotExists`、
|
|
158
|
-
`SqlSubQuery.In`、`SqlSubQuery.NotIn`、`SqlSubQuery.Scalar` 和
|
|
159
|
-
`SqlSubQuery.Count`。
|
|
160
|
-
返回的是 SQL 片段,数据值仍要参数化。
|
|
161
|
-
|
|
162
|
-
## 导航属性
|
|
163
|
-
|
|
164
|
-
`[Navigate]` 支持 `NavigateType.OneToOne`、`NavigateType.OneToMany`、
|
|
165
|
-
`NavigateType.ManyToMany`;加载入口:
|
|
166
|
-
|
|
167
|
-
- `IncludeOne`
|
|
168
|
-
- `IncludeMany`
|
|
169
|
-
- `IncludeManyToMany`
|
|
170
|
-
|
|
171
|
-
实现使用批量 IN,避免逐行 N+1。仍要限制主结果规模。
|
|
172
|
-
|
|
173
|
-
## CodeFirst
|
|
174
|
-
|
|
175
|
-
```csharp
|
|
176
|
-
dbSession.CreateTable<SysUser>();
|
|
177
|
-
dbSession.SyncSchema(typeof(SysUser), typeof(Order));
|
|
178
|
-
var exists = dbSession.TableExists("sys_user");
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
`CreateTable<T>(dropIfExists: true)` 是破坏性操作,只可在明确授权的隔离环境使用。
|
|
182
|
-
实体索引可用 `[Index]` 声明;Microi 低代码业务表的运行时索引仍必须走 Manifest/MCP。
|
|
183
|
-
|
|
184
|
-
## 读写分离
|
|
185
|
-
|
|
186
|
-
```csharp
|
|
187
|
-
var router = new ReadWriteRouter(master);
|
|
188
|
-
router.AddSlave(slave1, weight: 1);
|
|
189
|
-
router.AddSlave(slave2, weight: 2);
|
|
190
|
-
|
|
191
|
-
var read = router.GetReadSession();
|
|
192
|
-
var write = router.GetWriteSession();
|
|
193
|
-
|
|
194
|
-
using (router.ForceMaster())
|
|
195
|
-
{
|
|
196
|
-
var latest = router.GetReadSession().From<SysUser>().ToList();
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
支持加权轮询、摘除和回退。事务与读自己刚写的数据必须读主。
|
|
201
|
-
|
|
202
|
-
## 分库分表
|
|
203
|
-
|
|
204
|
-
表名路由:
|
|
205
|
-
|
|
206
|
-
- `ShardingRouter.MonthlyTable`
|
|
207
|
-
- `ShardingRouter.HashModTable`
|
|
208
|
-
- `ShardingRouter.ModTable`
|
|
209
|
-
|
|
210
|
-
数据库路由:
|
|
211
|
-
|
|
212
|
-
- `DbShardingRouter.AddNode`
|
|
213
|
-
- `RouteByHash`
|
|
214
|
-
- `AllNodes`
|
|
215
|
-
|
|
216
|
-
稳定 Hash 使用 FNV-1a。跨分片事务、全局唯一键、分页排序和聚合需要业务层明确设计。
|
|
217
|
-
|
|
218
|
-
## 监控与缓存
|
|
219
|
-
|
|
220
|
-
```csharp
|
|
221
|
-
Dos.ORM.Section.SlowSqlThresholdMs = 1000;
|
|
222
|
-
Dos.ORM.Section.OnSlowSql = (cmd, elapsed, operation) =>
|
|
223
|
-
{
|
|
224
|
-
// 记录脱敏 SQL 模板、耗时和关联 Id;不要记录密钥参数
|
|
225
|
-
};
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
反序列化器、实体元数据和字段名缓存是进程内优化,允许节点重启后重建;
|
|
229
|
-
不能作为跨节点业务事实。查询缓存使用滑动过期,写后按业务失效。
|
|
1
|
+
# Dos.ORM API 参考
|
|
2
|
+
|
|
3
|
+
## 数据库 Provider
|
|
4
|
+
|
|
5
|
+
| DatabaseType | Provider |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `SqlServer` | SQL Server 2000 |
|
|
8
|
+
| `SqlServer9` | SQL Server 2005+ |
|
|
9
|
+
| `MySql` | MySQL |
|
|
10
|
+
| `Oracle` | Oracle |
|
|
11
|
+
| `PostgreSql` | PostgreSQL |
|
|
12
|
+
| `DaMeng` | 达梦 |
|
|
13
|
+
| `KingBase` | 人大金仓 |
|
|
14
|
+
| `Sqlite3` | SQLite |
|
|
15
|
+
| `MsAccess` | Access |
|
|
16
|
+
|
|
17
|
+
兼容协议数据库仍需目标库实测,不能只凭协议名称判定所有 DDL、分页和 BulkCopy 一致。
|
|
18
|
+
|
|
19
|
+
默认会话入口是 `DbSession.Default`;多数据库、读写分离和分片场景使用明确的
|
|
20
|
+
`DbSession` 实例,避免把默认连接误用于其它租户或数据库。
|
|
21
|
+
|
|
22
|
+
## 实体
|
|
23
|
+
|
|
24
|
+
```csharp
|
|
25
|
+
[TableName("sys_user")]
|
|
26
|
+
public class SysUser : Entity
|
|
27
|
+
{
|
|
28
|
+
public string Id { get; set; }
|
|
29
|
+
public string Account { get; set; }
|
|
30
|
+
public DateTime CreateTime { get; set; }
|
|
31
|
+
|
|
32
|
+
public override Field[] GetFields() => new[] { _.Id, _.Account, _.CreateTime };
|
|
33
|
+
public override object[] GetValues() => new object[] { Id, Account, CreateTime };
|
|
34
|
+
public override Field GetIdentityField() => _.Id;
|
|
35
|
+
|
|
36
|
+
public sealed class _
|
|
37
|
+
{
|
|
38
|
+
public static readonly Field Id = new Field("Id", "sys_user");
|
|
39
|
+
public static readonly Field Account = new Field("Account", "sys_user");
|
|
40
|
+
public static readonly Field CreateTime = new Field("CreateTime", "sys_user");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`Entity.GetFields()` 的字段顺序也是批量写入和 CodeFirst 映射依据;实体声明、
|
|
46
|
+
字段数组与数据库列变更必须同步。
|
|
47
|
+
|
|
48
|
+
## 查询链
|
|
49
|
+
|
|
50
|
+
| API | 作用 |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `From<T>()` / `From("table")` | 查询入口 |
|
|
53
|
+
| `Where(predicate)` / `Where(WhereClip)` | 条件 |
|
|
54
|
+
| `OrderBy` / `OrderByDescending` | 排序 |
|
|
55
|
+
| `GroupBy` / `Having` | 分组 |
|
|
56
|
+
| `Select` / `AddSelect` | 选择字段 |
|
|
57
|
+
| `Distinct` / `Top` / `Page` | 去重、Top、分页 |
|
|
58
|
+
| `InnerJoin/LeftJoin/RightJoin/CrossJoin/FullJoin` | Join |
|
|
59
|
+
| `Union/UnionAll` | 集合联合 |
|
|
60
|
+
| `SetCacheTimeOut` / `Refresh` | 查询缓存/绕过缓存 |
|
|
61
|
+
| `ToList/ToListAsync` | 列表 |
|
|
62
|
+
| `ToFirst/ToFirstAsync` | 第一条或 null |
|
|
63
|
+
| `ToFirstDefault` | 第一条或 new 实体 |
|
|
64
|
+
| `ToScalar/ToScalarAsync` | 标量 |
|
|
65
|
+
| `ToDataReader` / `ToDataTable/ToDataTableAsync` | Reader/DataTable |
|
|
66
|
+
| `ToEnumerable` | 流式枚举 |
|
|
67
|
+
| `Count/CountAsync` | 计数 |
|
|
68
|
+
| `ExecuteNonQuery/ExecuteNonQueryAsync` | 非查询 |
|
|
69
|
+
|
|
70
|
+
查询缓存入口的完整成员名是 `FromSection.SetCacheTimeOut`。缓存 Key 包含 SQL
|
|
71
|
+
与参数值,但写后失效、租户隔离和多节点一致性仍由业务负责。
|
|
72
|
+
|
|
73
|
+
```csharp
|
|
74
|
+
var users = await dbSession.From<SysUser>()
|
|
75
|
+
.Where(u => u.Account == account)
|
|
76
|
+
.OrderByDescending(u => u.CreateTime)
|
|
77
|
+
.Page(20, 1)
|
|
78
|
+
.ToListAsync();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## WhereClip
|
|
82
|
+
|
|
83
|
+
```csharp
|
|
84
|
+
var where = new Where<SysUser>();
|
|
85
|
+
where.And(u => u.Status == 1);
|
|
86
|
+
if (!string.IsNullOrWhiteSpace(keyword))
|
|
87
|
+
where.And(u => u.Name.Like(keyword));
|
|
88
|
+
if (deptIds?.Any() == true)
|
|
89
|
+
where.And(u => u.DeptId.In(deptIds));
|
|
90
|
+
|
|
91
|
+
var list = dbSession.From<SysUser>()
|
|
92
|
+
.Where(where.ToWhereClip())
|
|
93
|
+
.ToList();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
支持比较、`Like/NotLike/StartsWith/EndsWith`、`In/NotIn` 和 NULL。
|
|
97
|
+
|
|
98
|
+
## 原生 SQL
|
|
99
|
+
|
|
100
|
+
```csharp
|
|
101
|
+
var users = dbSession
|
|
102
|
+
.FromSql("SELECT Id,Account FROM sys_user WHERE Status=@p0")
|
|
103
|
+
.AddInParameter("@p0", 1)
|
|
104
|
+
.ToList<SysUser>();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
动态值只走参数;动态标识符先从固定白名单映射。
|
|
108
|
+
Provider 的标识符替换最终由 `DataUtils.FormatSQL` 完成;不要绕过该步骤手工
|
|
109
|
+
拼接用户输入的表名或字段名。
|
|
110
|
+
|
|
111
|
+
## 写入
|
|
112
|
+
|
|
113
|
+
```csharp
|
|
114
|
+
dbSession.Insert(entity);
|
|
115
|
+
dbSession.Insert(list);
|
|
116
|
+
dbSession.Update<SysUser>(u => u.Status, 0, u => u.Id == id);
|
|
117
|
+
dbSession.Delete<SysUser>(u => u.Id == id);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
批量:
|
|
121
|
+
|
|
122
|
+
```csharp
|
|
123
|
+
var affected = dbSession.BulkInsert(list, batchSize: 5000, bulkCopyTimeoutSeconds: 600);
|
|
124
|
+
var affectedAsync = await dbSession.BulkInsertAsync(list, batchSize: 5000, ct: token);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
原生优选:
|
|
128
|
+
|
|
129
|
+
- SQL Server:SqlBulkCopy
|
|
130
|
+
- MySQL:MySqlBulkCopy
|
|
131
|
+
- PostgreSQL/KingBase:Binary COPY
|
|
132
|
+
- Oracle/达梦/SQLite/Access:多行参数化 INSERT 回退
|
|
133
|
+
|
|
134
|
+
批大小 5000 只是起点;按行宽、索引、日志、网络和数据库负载测量。
|
|
135
|
+
|
|
136
|
+
## Upsert
|
|
137
|
+
|
|
138
|
+
```csharp
|
|
139
|
+
dbSession.Upsert(user, SysUser._.Account);
|
|
140
|
+
await dbSession.UpsertAsync(
|
|
141
|
+
user,
|
|
142
|
+
ct: token,
|
|
143
|
+
conflictFields: new[] { SysUser._.Account });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
各 Provider 使用 `ON DUPLICATE KEY`、`ON CONFLICT`、`MERGE` 或更新后插入回退。
|
|
147
|
+
冲突字段必须有数据库唯一约束。
|
|
148
|
+
|
|
149
|
+
## SqlFunc 与子查询
|
|
150
|
+
|
|
151
|
+
`SqlFunc` 提供 `SqlFunc.IfNull`、`SqlFunc.IIF`、`SqlFunc.Length`、
|
|
152
|
+
`SqlFunc.Substring`、`SqlFunc.Now`、`SqlFunc.DateDiff`、
|
|
153
|
+
`SqlFunc.JsonValue`、`SqlFunc.Concat`、`SqlFunc.Upper`、`SqlFunc.Lower`、
|
|
154
|
+
`SqlFunc.Trim`、`SqlFunc.Abs`、`SqlFunc.Round`、`SqlFunc.Count`、
|
|
155
|
+
`SqlFunc.Sum`、`SqlFunc.Avg`、`SqlFunc.Min`、`SqlFunc.Max` 的 Provider 方言。
|
|
156
|
+
|
|
157
|
+
`SqlSubQuery` 提供 `SqlSubQuery.Exists`、`SqlSubQuery.NotExists`、
|
|
158
|
+
`SqlSubQuery.In`、`SqlSubQuery.NotIn`、`SqlSubQuery.Scalar` 和
|
|
159
|
+
`SqlSubQuery.Count`。
|
|
160
|
+
返回的是 SQL 片段,数据值仍要参数化。
|
|
161
|
+
|
|
162
|
+
## 导航属性
|
|
163
|
+
|
|
164
|
+
`[Navigate]` 支持 `NavigateType.OneToOne`、`NavigateType.OneToMany`、
|
|
165
|
+
`NavigateType.ManyToMany`;加载入口:
|
|
166
|
+
|
|
167
|
+
- `IncludeOne`
|
|
168
|
+
- `IncludeMany`
|
|
169
|
+
- `IncludeManyToMany`
|
|
170
|
+
|
|
171
|
+
实现使用批量 IN,避免逐行 N+1。仍要限制主结果规模。
|
|
172
|
+
|
|
173
|
+
## CodeFirst
|
|
174
|
+
|
|
175
|
+
```csharp
|
|
176
|
+
dbSession.CreateTable<SysUser>();
|
|
177
|
+
dbSession.SyncSchema(typeof(SysUser), typeof(Order));
|
|
178
|
+
var exists = dbSession.TableExists("sys_user");
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`CreateTable<T>(dropIfExists: true)` 是破坏性操作,只可在明确授权的隔离环境使用。
|
|
182
|
+
实体索引可用 `[Index]` 声明;Microi 低代码业务表的运行时索引仍必须走 Manifest/MCP。
|
|
183
|
+
|
|
184
|
+
## 读写分离
|
|
185
|
+
|
|
186
|
+
```csharp
|
|
187
|
+
var router = new ReadWriteRouter(master);
|
|
188
|
+
router.AddSlave(slave1, weight: 1);
|
|
189
|
+
router.AddSlave(slave2, weight: 2);
|
|
190
|
+
|
|
191
|
+
var read = router.GetReadSession();
|
|
192
|
+
var write = router.GetWriteSession();
|
|
193
|
+
|
|
194
|
+
using (router.ForceMaster())
|
|
195
|
+
{
|
|
196
|
+
var latest = router.GetReadSession().From<SysUser>().ToList();
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
支持加权轮询、摘除和回退。事务与读自己刚写的数据必须读主。
|
|
201
|
+
|
|
202
|
+
## 分库分表
|
|
203
|
+
|
|
204
|
+
表名路由:
|
|
205
|
+
|
|
206
|
+
- `ShardingRouter.MonthlyTable`
|
|
207
|
+
- `ShardingRouter.HashModTable`
|
|
208
|
+
- `ShardingRouter.ModTable`
|
|
209
|
+
|
|
210
|
+
数据库路由:
|
|
211
|
+
|
|
212
|
+
- `DbShardingRouter.AddNode`
|
|
213
|
+
- `RouteByHash`
|
|
214
|
+
- `AllNodes`
|
|
215
|
+
|
|
216
|
+
稳定 Hash 使用 FNV-1a。跨分片事务、全局唯一键、分页排序和聚合需要业务层明确设计。
|
|
217
|
+
|
|
218
|
+
## 监控与缓存
|
|
219
|
+
|
|
220
|
+
```csharp
|
|
221
|
+
Dos.ORM.Section.SlowSqlThresholdMs = 1000;
|
|
222
|
+
Dos.ORM.Section.OnSlowSql = (cmd, elapsed, operation) =>
|
|
223
|
+
{
|
|
224
|
+
// 记录脱敏 SQL 模板、耗时和关联 Id;不要记录密钥参数
|
|
225
|
+
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
反序列化器、实体元数据和字段名缓存是进程内优化,允许节点重启后重建;
|
|
229
|
+
不能作为跨节点业务事实。查询缓存使用滑动过期,写后按业务失效。
|