【开源】跨语言·跨平台·跨数据库(3) —— 为用宝框架增加ORM,让AI执行

【开源】跨语言·跨平台·跨数据库(3) ------为用宝框架增加ORM,让AI执行

2026-07-13

作者:周方勇 / 咏方舟-长江支流(金质打印通、用宝框架开源作者)

用宝框架 · 拥抱第一 · 一次书写 · 三端复用

用宝框架是轻量级企业级分层架构基架,也是开放的、可扩展的架构体系 。.NET Standard 2.0,零依赖,支持 MySQL / SQL Server / Oracle / SQLite并可扩展。SQL就是最好的跨平台语言可跨语言无缝迁移至鸿蒙 ArkTS 及 Java 技术栈,接口名、类名、方法签名三端完全一致

用宝架构开发的所有应用,可直接移植到 Java/ArkTS,无需重新设计架构、无需重新分层、无需重新抽象业务逻辑,只需按目标语言语法做形式上的转换。

本文侧重:为用宝框架增加轻量级 ORM,在不改变核心基架的前提下,获得实体映射 + 自动 SQL 生成能力,增删改查完全不用写代码。本篇将20年前无泛型、无依赖注入、无EF时的轻量级设计重新整理,形成完整的设计文档与约束规范,让AI按照规范自动执行生成代码。当然,为了代码生成少些bug,我提供了之前源码,特别是CommandTextBuilder。人工不仅是设计师,更是有与AI沟通的能力,以及程序员协助调试Bug的能力,AI作为执行者将更大幅提升效率。



用宝架构 ORM 扩展设计总结(跨语言版)

前言:用宝框架的轻量与开放

用宝框架首先是轻量级 的------UserBaoTech.Foundation 核心库仅依赖 System.Text.Json,零 ORM 绑定,零重量级抽象,保持最小依赖和最大可移植性。

但用宝框架也是开放的------核心不预设任何具体实现,所有组件通过接口可替换、可扩展。这种设计既保障了基座的稳定性,也为上层功能的生长留出了空间。

本篇的目的,就是为用宝框架增加一个 ORM 扩展模块:让开发者在不改变核心基架的前提下,获得"实体映射 + 自动 SQL 生成 + 事件钩子"的便利能力。


本篇的目的,就是为用宝框架增加一个 ORM 扩展模块:让开发者在不改变核心基架的前提下,获得"实体映射 + 自动 SQL 生成 + 事件钩子"的便利能力。

💡 AI 时代的编程思想:人是设计师,AI 是执行者

以下设计不仅是给开发者阅读的编码依据,也是给 AI 执行的指令集。设计越详细、规范越清晰、约束越明确,AI 生成的代码质量就越高,越不需要人工修改。

你用宝框架定义好了"怎么写"(接口、基类、命名规范、跨语言约束),AI 只需要根据表结构填空生成"写什么"(实体、仓储、服务、控制器)。

这就是 AI 时代程序员的核心竞争力------从"写代码的人"进化为"设计架构、定义规范、指挥 AI 执行的人"。

同时,这个扩展模块必须继承用宝框架的跨语言设计约束

  • 接口定义中不使用 IList<T>List<T>IDictionary<TKey, TValue> 等特定语言集合类型
  • 统一使用 数组 T[] 表示集合,因为数组在 C#、Java、ArkTS 中都是原生语法,不需要额外引入命名空间或类库
  • 这一原则贯穿整个 ORM 模块的设计,确保用宝框架的业务代码可以直接"拷过去用",而不是靠"翻译器"转换

这就是用宝框架的"轻量·开放·跨语言"三位一体设计。

这套轻量级 ORM 的设计,早在 2007年就已在 CSDN 上公开分享(当时用的是 2004 年写的源码),至今约 20 年。相关文章:

只是今天,在用宝框架上,我根据框架轻量化特点,应用跨平台并通用于java、ArcTS通用语言,重新设计。你如果将本篇投喂给AI,AI也可以帮你完成代码书写,但如果再把用宝技术轻量框架的设计一起发给AI,那生成的ORM代码就更适合用宝框架。

【开源】跨语言·跨平台·跨数据库(1) ------ 用宝技术轻量框架 AI 开发指南

【开源】跨语言·跨平台·跨数据库(2) ------ 用宝轻量框架设计必读

一、用宝架构现有核心(已有,无需改动)

  • 命名空间UserBaoTech.Foundation

  • 核心抽象

    • IEntity<TKey>:实体基接口(IdCreatedAtUpdatedAtIsDeleted
    • IRepository<T>:泛型仓储接口(CRUD + 执行 SQL)
    • RepositoryBase<T>:仓储基类,提供默认 CRUD 实现,子类需实现表名、映射、插入/更新值
    • IDataAccessExecutor:数据访问执行器,封装连接、事务、SQL 执行及方言适配(参数前缀、分页、自增回读)
    • IUnitOfWork:工作单元,管理事务边界
    • ServiceBase<TParam,TResult> / KeyServiceBase<TResult>:业务服务基类,模板方法模式
    • MessageResult<T>:统一返回格式
    • QueryParametersBase:查询参数基类
    • 基础设施接口:ILoggerICacheProviderIConfigProvider(可插拔)
  • 设计原则 :轻量、零依赖(仅 System.Text.Json)、跨语言可迁移、接口优先、基类提供默认实现。

二、ORM 扩展目标

不改变现有核心基架 的前提下,增加一个可选的 ORM 模块,提供:

  1. 实体映射:通过特性标记或手写元数据,将实体类与数据库表、字段、主键关联。
  2. 自动 SQL 生成 :根据实体元数据自动生成 INSERT / UPDATE / DELETE / SELECT 语句,无需手动写 SQL。
  3. 实体存取接口 :提供类似旧 IEntityAccess 的增删改查操作,并通过虚方法钩子(而非事件委托)提供扩展点,方便业务定制。
  4. 与现有框架无缝集成 :复用 IDataAccessExecutor 执行 SQL,复用 IUnitOfWork 管理事务。

三、新增命名空间与核心接口

命名空间:UserBaoTech.Foundation.ORM

1. 可映射实体接口 IMapEntity<TKey>

继承自 IEntity<TKey>,增加表结构元数据获取方法:

csharp 复制代码
public interface IMapEntity<TKey> : IEntity<TKey>
{
    // 表名
    string TableName { get; }
    
    // 主键列表(支持复合主键)
    string[] PrimaryKeys { get; }
    
    // 字段列表
    string[] GetFields();
    
    // 字段值列表(与 GetFields() 顺序一致)
    object[] GetFieldValues();
    
    // 主键值列表
    object[] GetPrimaryKeyValues();
    
    // 从数据源加载实体
    void LoadFrom(IEntityDataSource source);
}
csharp 复制代码
// 跨语言数据源接口
// C# 端适配 IDataReader
// Java 端适配 ResultSet
// ArkTS 端适配 relationalStore.ResultSet
public interface IEntityDataSource
{
    object GetValue(string fieldName);
}

元数据提供方式(两种可选):

  • 特性方式 :使用 [Table][Column][Key] 等特性标记实体类,IMapEntity 的实现通过反射读取。
  • 手写方式 :实体类直接实现 IMapEntity 接口,在 GetFields() 等方法中返回字段列表(兼容旧代码风格)。

例如

csharp 复制代码
// 特性方式基类
[Table("Products")]
public class Product : AttributeMapEntity<Product>
{
    [Column("Id")]
    [Key]
    public string Id { get; set; }
    
    [Column("Name")]
    public string Name { get; set; }
}

// 手写方式基类
public class Product : ManualMapEntity<Product>
{
    public string Id { get; set; }
    public string Name { get; set; }
    
    protected override string[] GetFieldsCore()
    {
        return new string[] { "Id", "Name" };
    }
    
    protected override object[] GetFieldValuesCore()
    {
        return new object[] { Id, Name };
    }
}

### 2. 实体存取接口 `IMap

EntityAccess`

定义对单个实体类型的增删改查操作:

csharp 复制代码
public interface IMapEntityAccess<TEntity> where TEntity : class, IMapEntity<string>
{
    // 当前实体实例
    TEntity Entity { get; set; }
    
    // 增删改查
    int Insert();
    int Update();
    int Delete();
    bool FillByPK();  // 根据主键填充当前实体
}

3. 基类 MapEntityAccessBase<TEntity>

实现 IMapEntityAccess<TEntity>,提供默认行为:

  • 通过构造函数注入 IDataAccessExecutor(复用框架底层)及非特定语言的 IEntityDataSource
  • 内部使用 CommandTextBuilder(见下文)根据实体元数据自动生成 SQL
  • 执行 SQL 时自动处理参数顺序(先字段值,后主键值,确保 UPDATE 语句正确)
  • 注意 :每个操作前后不再使用 C# 的 event/delegate 机制,改用虚方法钩子(OnBeforeInsertOnAfterInserted 等),确保 Java/ArkTS 端通过继承重写即可获得完全一致的扩展能力
  • 引用 IUserBaoException 实现跨语言异常隔离
csharp 复制代码
public abstract class MapEntityAccessBase<TEntity> : IMapEntityAccess<TEntity>
    where TEntity : class, IMapEntity<string>
{
    // 构造函数:注入 IEntityDataSource 和 IDataAccessExecutor
    protected MapEntityAccessBase(IEntityDataSource dataSource, IDataAccessExecutor executor)
    {
    }

    // 实现接口
    public TEntity Entity { get; set; }
    public int Insert() { }
    public int Update() { }
    public int Delete() { }
    public bool FillByPK() { }

    // 钩子方法(虚方法,子类可重写)
    // 返回 bool:true 继续执行,false 取消当前操作
    protected virtual bool OnBeforeInsert()
    {
        return true;
    }
    protected virtual bool OnAfterInserted()
    {
        return true;
    }
    protected virtual bool OnBeforeUpdate()
    {
        return true;
    }
    protected virtual bool OnAfterUpdated()
    {
        return true;
    }
    protected virtual bool OnBeforeDelete()
    {
        return true;
    }
    protected virtual bool OnAfterDeleted()
    {
        return true;
    }
    protected virtual bool OnError(IUserBaoException ex)
    {
        return false;
    }

    // 内部 SQL 拼装器
    private static class CommandTextBuilder
    {
        // ...
    }
}

所有操作钩子统一行为:返回 true 继续流程,false 中断后续操作。这个改动将保留到后续的ORM扩展设计总结中。

设计要点

  • 钩子方法采用标准块体写法({ return true; }),三端可直接拷贝
  • 虚方法重载在 C#/Java/ArkTS 中写法基本一致,是跨语言扩展点的最佳实践
  • 不使用 C# 的 => 箭头表达式,避免三端语法差异

4. 内部类 CommandTextBuilder

仅供 MapEntityAccessBase 内部使用,不对外公开。

  • 根据表名、字段列表、主键列表生成 INSERT / UPDATE / DELETE / SELECT 模板
  • 参数占位符统一用 @字段名(不区分数据库),最终由 IDataAccessExecutor 自动适配方言
  • UPDATE 语句自动排除主键字段(主键不作为 SET 子句)
  • 提供参数列表生成方法(区分普通字段与主键字段,保证顺序正确)

四、与现有架构的集成点

  • 数据执行MapEntityAccessBase 内部持有 IDataAccessExecutor,通过它执行所有 SQL,自动获得方言适配、连接管理、事务支持。
  • 事务管理 :开发者在使用 IMapEntityAccess 时,外部用 IUnitOfWork 包围,即可实现多实体事务(与现有 Repository 方式一致)。
  • 服务层MapEntityAccessBase 可以作为服务层的基础,也可以与现有 ServiceBase 协同使用(例如在 Service 中调用 IMapEntityAccess)。

五、扩展点设计(虚方法钩子,而非事件委托)

每个操作(Insert / Update / Delete)前后均提供虚方法钩子,供子类重写:

五、扩展点设计(虚方法钩子,而非事件委托)

每个操作(Insert / Update / Delete)前后均提供虚方法钩子,供子类重写:

所有钩子统一返回 bool,含义如下:

返回值 含义
true 继续执行后续流程
false 中断后续操作

各钩子触发时机与用途:

钩子方法 触发时机 返回 false 的效果
OnBeforeInsert() 执行 INSERT 前 取消本次插入
OnAfterInserted() INSERT 成功后 阻止后续提交或后续处理
OnBeforeUpdate() 执行 UPDATE 前 取消本次更新
OnAfterUpdated() UPDATE 成功后 阻止后续提交或后续处理
OnBeforeDelete() 执行 DELETE 前 取消本次删除
OnAfterDeleted() DELETE 成功后 阻止后续提交或后续处理
OnError(IUserBaoException) 发生异常时 阻止异常向外抛出(已处理)

为什么用虚方法钩子,而不是 C# 的 event/delegate?

方式 C# Java ArkTS 三端一致性
event / delegate 原生支持 ❌ 无直接对应 ❌ 无直接对应
虚方法重载 virtual 原生支持 原生支持 ✅ 写法基本一致

event/delegate 是 C# 特有语法,Java 和 ArkTS 没有直接对应。使用虚方法钩子,三端开发者都可以通过继承基类、重写方法来实现完全相同的扩展逻辑,代码可以直接拷贝,只需调整语法格式。

为什么后置钩子也返回 bool

前置钩子返回 false 可以取消操作(如参数校验不通过),后置钩子返回 false 同样有意义------例如插入成功后检查返回结果,发现异常需要阻止后续提交;或者删除成功后触发某些业务逻辑失败,需要中断后续流程。统一返回 bool 让所有扩展点都具备"继续/中断"的控制能力,灵活性更高。

业务方可以通过重写钩子实现:

  • 操作前校验(如权限检查、字段自动填充)
  • 操作后日志记录、缓存刷新
  • 操作后条件判断,决定是否继续提交
  • 取消操作(通过返回 false
  • 异常处理与恢复

六、跨语言设计约束(重要)

为保持用宝框架"一次书写,三端复用"的核心能力,ORM 模块必须遵守:

禁止使用 应使用 原因
IList<T> / List<T> T[](数组) 数组在 C#、Java、ArkTS 中都是原生语法
IDictionary<TKey,TValue> 简单类型或数组 跨语言边界尽量用简单类型
LINQ 表达式 直接代码逻辑 LINQ 在 Java/ArkTS 中无直接对应
动态类型(dynamic 强类型或 object Java/ArkTS 不支持动态
event / delegate 虚方法钩子 event/delegate 是 C# 特有语法
=> 箭头表达式 标准块体 { return ...; } 避免三端语法差异

所有接口定义、方法签名、属性类型必须使用跨语言原生类型。

七、注意事项与边界

  1. 此模块为可选扩展 ,不影响现有 UserBaoTech.Foundation 核心基架。
  2. 不兼容旧代码,但借鉴旧设计思想(虚方法钩子、参数顺序处理)。
  3. 主键类型默认 string (GUID),但 IMapEntity<TKey> 支持泛型主键类型。
  4. 复合主键PrimaryKeys 支持多个字段,GetPrimaryKeyValues() 返回对应顺序的值。
  5. SQL 生成:所有 SQL 均使用参数化查询,防止注入。
  6. 所有集合返回类型使用 T[],保持跨语言一致性。

八、对新 AI 的生成指令

基于以上设计,请生成 UserBaoTech.Foundation.ORM 命名空间下的完整代码文件:

  1. IMapEntity.cs(接口定义,所有集合类型用 T[]
  2. IMapEntityAccess.cs(接口定义)
  3. MapEntityAccessBase.cs(基类实现,含 CommandTextBuilder 内部类,所有集合类型用 T[],无 event/delegate,钩子用虚方法)
  4. 示例实体 Product 展示特性标记方式(用于测试,不强制)

生成时遵循用宝框架风格:

  • 使用 .NET Standard 2.0
  • 无第三方依赖
  • 所有集合返回类型使用 T[],保持跨语言一致性
  • 方法命名清晰,注释完整
  • 不使用 event / delegate,扩展点用虚方法钩子
  • 不使用 => 箭头表达式,用标准块体写法
  • 内部 CommandTextBuilder 的参数占位符处理与 DataAccessExecutor 的方言适配兼容
  • 错误处理引用 IUserBaoException,不暴露 C# 特有的 Exception 类型

反馈与交流 :欢迎在评论区留言或私信交流。如果你正在寻找一套 不用 EF、不用 Dapper、可跨语言迁移 的轻量级基架,用宝框架或许是一个值得尝试的选择。


用宝框架,拥抱第一 · 一次书写 · 三端复用------不仅是用户的朋友,而且是用户的宝贝

相关推荐
小白狮ww1 小时前
告别「机械念经」:TADA-1b 让模型「说人话」
人工智能·语音识别·语音生成·ai声音
AliCloudROS1 小时前
一次真实录屏:我只说每月别超过 200 块,小程序后端就搭好了
运维·人工智能·云计算
code_pgf1 小时前
具身智能的核心组成部分及其作用
人工智能·机器人
长风2301 小时前
Day 16:大屏呈现——管理层视角 Dashboard 设计
人工智能·安全
User_芊芊君子2 小时前
实测参赛|用飞算JavaAI快速落地企业项目招投标管理系统
人工智能·ai·amd
还好还好不是吗2 小时前
MatrixMedia v0.10.x 更新:B站封面自定义 + 二开指南,开源项目的开发者体验再升级
electron·开源
深海鱼在掘金2 小时前
深入浅出RAG——第2章:文本嵌入 —— 让计算机理解语义的桥梁
人工智能
mit6.8242 小时前
VLM Wiki
人工智能
工业甲酰苯胺2 小时前
AI×JNPF实战:3个案例拆解企业数智转型核心逻辑
大数据·数据库·人工智能·低代码