1.1 几款流行的 ORM 架构设计 — 对比与驰骋 BPM 选型指南
文档性质:技术宣传 / 方案选型
版本:2026-06
驰骋 ORM 依据:CCFlow/Components/BP.En30
姊妹文档:驰骋 BPM ORM 设计技术报告(源码级深度剖析)
写在前面:ORM 不是「引个包就能 CRUD」
对象关系映射(ORM)解决的是业务对象与关系型数据库之间的鸿沟。但二十余年演进下来,业界早已分化出多种架构哲学——有的追求「像写 C# 一样写查询」,有的追求「SQL 零损耗」,有的则把 ORM 升格为企业应用元数据框架。
选错 ORM,代价往往不在第一天,而在第二年:表单要重做、主从表要手写、流程表单与组织权限无法共用一套字段语义、国产化数据库要逐条改 SQL……
本文列出六类主流 ORM 架构,并将驰骋 BPM 自研 ORM(BP.En30)作为同等对比项,从性能、扩展性、架构能力三个维度做深层次评估,帮助您在「通用业务系统」与「流程 + 低代码 + 组织一体化平台」之间做出正确判断。
一、六类主流 ORM 架构一览
1.1 架构地图(一句话定性)
| 类型 | 代表产品 | 核心隐喻 | 一句话 |
|---|---|---|---|
| 标准全功能 ORM | Entity Framework Core、Hibernate/JPA | 智能翻译官 | 用类与导航属性描述世界,框架生成 SQL 并跟踪变更 |
| 微 ORM | Dapper、SqlMapper | 精密扳手 | 几乎不抽象,手写 SQL + 轻量对象填充,极致性能 |
| SQL 映射器 | MyBatis / MyBatis-Plus | 合同工 | XML/注解写 SQL,Java/C# 只负责调用与映射 |
| 类型安全 SQL 构建器 | jOOQ、SqlKata | 语法检查员 | 用代码拼 SQL,编译期校验,兼顾灵活与类型 |
| Active Record | Ruby on Rails ActiveRecord、Laravel Eloquent | 一物一表 | 模型类即表,链式查询,快速 CRUD |
| 元数据驱动应用 ORM | 驰骋 BP.En30(Map/Attr/Entity) | 蓝图 + 施工一体化 | 一份 Map 同时描述表结构、控件、主从、权限与查询 |
1.2 架构关系图
读图要点:驰骋 ORM 与 EF/Hibernate 在「抽象程度」上相近,但在「应用语义」(表单、主从、组织、流程)上显著更高——这是品类差异,不是简单的「谁更强」。
二、直观对比:用场景说话
2.1 盖房子类比
| ORM 类型 | 类比 | 擅长 | 不擅长 |
|---|---|---|---|
| EF Core / Hibernate | 标准化住宅模块 | 卧室、客厅、水电管线有统一规范 | 每户要完全不同的户型时要大量定制 |
| Dapper | 自己买砖砌墙 | 结构简单、要省料、要快 | 复杂户型图纸得自己画 |
| MyBatis | 施工队按图纸干 | SQL 可控、DBA 友好、报表复杂查询 | 图纸(XML)多了难维护 |
| jOOQ | 带校核的施工图 | 复杂 SQL 组合、类型安全 | 不管 UI、不管表单 |
| Active Record | 精装小户型 | 博客、电商 SKU、快速上线 | 超大复杂领域模型易臃肿 |
| 驰骋 ORM | 园区总体规划 + 单体楼一体化 | 流程表单、主从、多对多、组织权限、低代码设计器 | 与 BPM 无关的纯 .NET 微服务 |
2.2 开发同一需求要多少「额外工作」
以**「用户表 + 部门外键 + 一人多部门维护 + 列表查询 + 权限控制」**为例:
| 能力项 | EF Core | MyBatis | Dapper | 驰骋 ORM |
|---|---|---|---|---|
| 实体/表映射 | 特性或 Fluent API | XML/注解 | 手写 | Map.AddTB* / AddDDLEntities |
| 多部门维护 UI | 自研 | 自研 | 自研 | AttrsOfOneVSM.AddBranches 内置 |
| 列表查询条件 | LINQ 或动态表达式 | 动态 SQL 片段 | 拼字符串 | SearchNormals 声明式 |
| 数据范围权限 | 过滤器/拦截器 自研 | 拦截器 自研 | 自研 | UAC + AddHidden 内建 |
| 与表单设计器打通 | 无 | 无 | 无 | Map ↔ Sys_MapAttr 双向 |
| 与流程选人引擎 | 无 | 无 | 无 | Port_* 实体 原生一体 |
结论(宣传核心):在驰骋 BPM 场景下,通用 ORM 只解决了约 30% 的问题(CRUD),其余 70%(主从、多对多维护、低代码、组织、权限)仍需重复建设;驰骋 ORM 在诞生之初就把这 70% 写进了 Map 元数据体系。
三、架构设计深度对比
3.1 元数据模型:谁描述「字段」?
| 维度 | 标准 ORM | 驰骋 ORM |
|---|---|---|
| 元数据载体 | 类属性、注解、Fluent | Map、Attr、Attrs(代码)+ Sys_MapAttr(库表) |
| 字段值存储 | 强类型属性 + 变更跟踪 | Row(Hashtable)弱类型 + 可选强类型封装 |
| 主键策略 | 约定或配置 | EntityNoName / EntityOID / EntityMyPK 基类约定 |
| SQL 生成 | Provider 翻译表达式树 | SqlBuilder + SQLCache 模板缓存 |
| 运行期动态表 | 困难(需迁移或 raw SQL) | GenerMap() 从设计器元数据合成 Map |
驰骋 ORM 自 2002 年起演进(EntityDBAccess 文件头仍标注创建时间 2002-10),2003 年完成 XML → Map/Attr/Attrs 架构定型,与 CCFlow/JFlow 共同成长二十余年——这不是「后来补的一层 DAO」,而是平台内核。
3.2 核心类层次(驰骋)
EnObj(Row + UAC + 默认值 @WebUser.*)
└── Entity(Insert / Update / Delete / Retrieve / CheckPhysicsTable)
├── EntityNoName → 主键 No(部门、用户、流程编号)
├── EntityOID → 主键 OID(运行实例、从表明细)
└── EntityMyPK → 主键 MyPK(DeptEmp、DeptEmpStation 等)
Entities(集合 + QueryObject 批量查询)
Map(物理表 + Attrs + EnDtl 从表 + AttrsOfOneVSM 多对多 + 查询 + 关联方法)
与市面 ORM 的本质分野:
市面 ORM 回答:「这一列是什么类型?」
驰骋 ORM 回答:「这一列是什么类型、用什么控件、绑哪个外键、在列表怎么搜、在主从里怎么展示、谁有权限改?」
四、多维度评估矩阵
4.1 综合评分(5 分制,面向企业级 BPM + 低代码场景)
| 评估维度 | EF Core | Hibernate | Dapper | MyBatis | jOOQ | Active Record | 驰骋 ORM |
|---|---|---|---|---|---|---|---|
| 纯 CRUD 开发效率 | 4.5 | 4.0 | 3.5 | 4.0 | 4.0 | 4.5 | 4.0 |
| 复杂 SQL / 报表性能 | 3.0 | 3.0 | 5.0 | 4.5 | 4.5 | 3.0 | 3.5 |
| 运行时内存占用 | 3.0 | 2.5 | 5.0 | 4.0 | 4.0 | 3.5 | 3.5 |
| 强类型 / IDE 重构 | 5.0 | 5.0 | 4.0 | 3.5 | 4.5 | 4.0 | 3.0 |
| 低代码 / 动态表单 | 1.0 | 1.0 | 1.0 | 1.5 | 1.0 | 2.0 | 5.0 |
| 主从 / 多对多内置 | 2.5 | 2.5 | 1.0 | 2.0 | 1.5 | 2.5 | 5.0 |
| 流程 + 组织一体化 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 5.0 |
| 多数据库 / 国产库 | 4.0 | 4.0 | 4.0* | 4.0* | 3.5 | 3.5 | 4.5 |
| 生态 / 招聘 / 社区 | 5.0 | 5.0 | 4.5 | 4.5 | 3.0 | 4.0 | 2.0 |
| 与 BPM 平台耦合度 | 可插拔 | 可插拔 | 可插拔 | 可插拔 | 可插拔 | 可插拔 | 平台内核 |
* 取决于手写 SQL 是否使用方言无关语法。
4.2 性能:深层次分析
(1)查询路径与开销
| 类型 | 典型路径 | 性能特征 |
|---|---|---|
| Dapper | SQL → IDataReader → 对象 | 开销最低,无表达式树、无变更跟踪 |
| 驰骋 ORM | QueryObject → SqlBuilder(SQLCache 缓存模板)→ DBAccess → 填充 Row | 接近「预生成 SQL + ADO.NET」,无 LINQ 翻译损耗 |
| EF Core | LINQ → 表达式树 → SQL 翻译 → 跟踪器 | 便利但有翻译成本;AsNoTracking 可改善读性能 |
| Hibernate | Session 一级缓存 + 脏检查 | 写路径方便,高并发需精细调 Session 边界 |
驰骋 ORM 的 SQLCache 在实体首次访问时缓存 Insert/Update/Delete/Select 模板,后续 CRUD 避免重复拼接 SQL——这是面向企业表单「字段多、结构稳定」场景的务实优化。
(2)批量与分页
- Dapper / MyBatis:批量操作、存储过程场景最优。
- 驰骋 ORM:
Entities+QueryObject批量检索;SFDBSrc内建多数据库分页方言(OracleROWNUM、MySQLLIMIT、SQL Server 主键分页等)。 - EF Core:
BulkExtensions等第三方补齐批量短板。
(3)性能结论(客观)
| 场景 | 推荐 |
|---|---|
| 亿级报表、复杂分析 SQL | Dapper / MyBatis 或只读从库 + 原生 SQL |
| 驰骋平台内标准表单 CRUD | 驰骋 ORM 足够快,且元数据收益远大于微秒级 ORM 差异 |
| 混合架构 | 核心流程走 BP.En30,重度统计旁路 DBAccess.RunSQL |
宣传要点:在 BPM 领域,瓶颈 rarely 在 ORM 反射,而在重复造轮子。驰骋 ORM 用略低于 Dapper 的裸性能,换取数量级的业务交付速度——这是正确的工程权衡。
4.3 扩展性:谁能「改字段不改全世界」?
| 扩展需求 | 标准 ORM | 驰骋 ORM |
|---|---|---|
| 新增业务字段 | 改实体类 + 迁移脚本 | 设计器加 MapAttr → GenerMap() 运行期生效 |
| 新增下拉数据源 | 新接口 + 前端组件 | SFTable(SQL/WS/WebAPI/Handler) |
| 新增从表 | 导航属性 + 前后端 CRUD | Map.AddDtl / MapDtl 声明式 |
| 多租户数据隔离 | 全局 QueryFilter | AddHidden("OrgNo", "@WebUser.OrgNo") |
| 外部组织集成 | 独立用户体系对接 | Port_* 视图模式 / OrganizationAPI 同步 |
| 跨语言(Java) | 各端各写 | JFlow 同语义 Map/Attr 移植 |
驰骋 ORM 的扩展性优势集中在 「元数据可运行期合成」——这是低代码平台的生死线,通用 ORM 通常不覆盖这一层。
4.4 架构能力:从数据层到应用层
| 架构能力 | 说明 | 驰骋 ORM 体现 |
|---|---|---|
| 自动 DDL | 按元数据建表扩列 | CheckPhysicsTable() — 先画表单后建表 |
| UI 元数据一体 | 字段即控件 | UIContralType:签名、附件、公文、地图… |
| 关联方法 | 实体上的业务动作 | RefMethod:改密、部门维护等 |
| 多数据源 | 跨库、外部 API | SFDBSrc + Map.DBSrc |
| 权限模型 | 行级/操作级 | UAC(增删改查可见) |
| AI 可读元数据 | 大模型理解表结构 | Map.ToDescForAI() 等演进方向 |
更换 ORM 的真实成本:若将驰骋 BPM 的 ORM 替换为 EF Core,需同步重写表单设计器、流程表单运行时、组织结构集成、选人 SQL、主从维护组件——相当于重写平台,而非替换一个 NuGet 包。
五、分类型优劣速查
5.1 Entity Framework Core / Hibernate(标准全功能 ORM)
优势
- 强类型 LINQ / Criteria,IDE 重构体验一流
- 变更跟踪,更新实体即可持久化
- 生态成熟:迁移、诊断、社区方案丰富
劣势
- 复杂 SQL、批量、报表场景需绕开 ORM
- 与低代码「运行期加字段」模型天然冲突
- N+1 查询、懒加载陷阱需团队规范
适用:.NET/Java 通用业务系统、领域驱动设计、与 BPM 无关的新项目。
5.2 Dapper(微 ORM)
优势
- 性能标杆,接近手写 ADO.NET
- 学习成本极低,SQL 完全可控
劣势
- 无元数据、无迁移、无主从抽象
- 字段映射、多表关联全靠约定与复制粘贴
适用:热点读、报表、物联网高频写入、ORM 旁的「性能快车道」。
5.3 MyBatis(SQL 映射器)
优势
- SQL 显式可见,DBA 与开发协同友好
- 动态 SQL 标签成熟,适合中国式复杂报表
劣势
- XML/注解双轨,大型项目映射文件臃肿
- 仍不解决 UI、表单、流程语义
适用:SQL 主导的后台、金融/政务复杂查询、Java 技术栈为主的数据中台。
5.4 jOOQ(类型安全 SQL 构建器)
优势
- 复杂 SQL 组合可读可测
- 编译期检查表名/列名,重构优于纯字符串
劣势
- 代码生成与数据库 schema 绑定紧
- 不管应用层 UI 与权限
适用:查询密集型后端、需要 DSL 但又不要 Hibernate 重量级的团队。
5.5 Active Record(Rails / Laravel 风格)
优势
- 模型即表,脚手架极速
- 链式 API 对 Web 全栈友好
劣势
- 胖模型 anti-pattern 风险
- 大型单体下测试与分层困难
适用:创业公司 MVP、内容管理、中小型 Web 产品。
5.6 驰骋 ORM — BP.En30(元数据驱动应用 ORM)★
优势
- 一份 Map,全栈消费:持久化、表单、列表、主从、多对多、权限同一套元数据
- 低代码原生:
Sys_MapAttr设计态 +GenerMap()运行态,用户可自定义字段 - 流程 + 组织内置:
Port_Emp/Dept/Station/DeptEmpStation与选人引擎同源 - 二十年生产验证:CCFlow/JFlow 全产品线承载
- 国产化数据库:Oracle、MySQL、PostgreSQL、SQL Server、达梦、人大金仓、瀚高等方言分支内建于
SqlBuilder/DBAccess - 主从与多对多一等公民:
EnDtl、AttrsOfOneVSM,非事后补丁
劣势(坦诚以建立信任)
- 非 .NET 标准 ORM,不能拿来给任意新项目「替代 EF Core」
Row弱类型模型,纯代码大型团队重构依赖检索而非编译器- 无 LINQ /
IQueryable,复杂 ad-hoc 查询不如 EF 优雅 - 与
DBAccess静态入口耦合紧,单元测试需数据库或封装层 - 招聘市场上专属技能面窄于 EF/MyBatis
适用:驰骋 BPM / CCFlow / JFlow 实施与二开;流程 + 表单 + 组织 + 权限一体化;需要用户自定义表单的企业低代码场景。
六、选型决策树
| 您的目标 | 推荐 |
|---|---|
| 上线驰骋 BPM,做流程审批 + 表单 + 组织 | 驰骋 ORM(平台内置) |
| 新业务中台,与 CCFlow 无关 | EF Core / MyBatis,不要强上驰骋 ORM |
| 驰骋项目中的海量统计大屏 | 驰骋 ORM + DBAccess 只读 SQL 旁路 |
| 外部系统已有 EF,对接 CCFlow | 组织数据用视图/API 集成,避免同表双 ORM |
七、为什么驰骋 BPM 坚持自研 ORM?
7.1 历史必然性
2002 年,团队需要的是可复用的企业应用框架,而非单纯的「对象映射库」。XML 描述映射 → 2003 年 Map/Attr/Attrs 代码化 → 与表单设计器、流程引擎、组织结构逐层融合——这是一条平台路线,不是库路线。
7.2 技术必然性
低代码的本质是:运行期才知道有哪些字段。标准 ORM 的强类型实体与编译期迁移,与这一前提存在结构性张力。驰骋选择 Row + 可合成 Map,是用工程上的「弱类型运行时」换取「强元数据语义」。
7.3 商业必然性
对甲方而言,价值不在「用了知名 ORM」,而在:
- 表单能否配置、流程能否落地、组织能否对接;
- 国产化数据库能否平滑切换;
- 实施周期能否以周计而非月计。
驰骋 ORM 正是为这三项交付目标而存在。
八、一图读懂:驰骋 ORM 在平台中的位置
九、结语
| 如果您要… | 请选择… |
|---|---|
| 业界最广泛的开发者生态与标准实践 | EF Core、Hibernate、MyBatis |
| 单机查询性能的极限 | Dapper |
| 流程、表单、组织、权限、低代码的一体化元数据平台 | 驰骋 BPM ORM(BP.En30) |
市面 ORM 解决的是 「对象如何映射到表」;
驰骋 ORM 解决的是 「企业应用如何从元数据一键生长」。
在正确的战场上,驰骋 ORM 不是 EF Core 的追赶者,而是 企业低代码 BPM 领域的事实标准实现——二十余年、数千家企业、与 CCFlow/JFlow 同源双栈,即是最好的背书。
附录 A:驰骋 ORM 核心 API 速览
// 实体声明(摘自平台惯例)
public class Demo : EntityNoName
{
public override Map EnMap
{
get
{
if (_enMap != null) return _enMap;
Map map = new Map("Demo_Table", "示例");
map.AddTBStringPK("No", null, "编号", true, false, 1, 50, 20);
map.AddTBString("Title", null, "标题", true, false, 0, 200, 30);
map.AddDDLEntities("FK_Dept", null, "部门", new Depts(), false);
_enMap = map;
return _enMap;
}
}
}
// 运行时使用
var en = new Demo("001");
en.RetrieveFromDBSources();
en.SetValByKey("Title", "新标题");
en.Update();
var ens = new Demos();
ens.RetrieveByAttr("FK_Dept", "1001");
附录 B:核心源码索引
| 类型 | 路径 | 说明 |
|---|---|---|
Map / Attr | En/MapExt/Map.cs、Attr.cs | 元数据根对象 |
Entity / Entities | En/Entity.cs、Entities.cs | 实体与集合 |
SqlBuilder | En/SqlBuilder.cs | 多方言 SQL 生成 |
SQLCache | En/SQLCache.cs | SQL 模板缓存 |
DBAccess | DA/DBAccess.cs | 数据库访问(2002 年起) |
MapAttr / MapData | Sys/MapAttr.cs、MapData.cs | 低代码设计态元数据 |
Emp / Dept | Port/Emp.cs、Dept.cs | 组织结构实体范例 |
驰骋 BPM — 用一套 ORM,撑起流程、表单与组织的低代码底座。

480

被折叠的 条评论
为什么被折叠?



