# TORM **Repository Path**: ThingsGateway/TORM ## Basic Information - **Project Name**: TORM - **Description**: TORM 是一个为 .NET 平台设计的轻量级、高性能 ORM(对象关系映射)框架。它提供了简洁流畅的 API,支持多种数据库,并针对高性能场景进行了深度优化。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 2 - **Created**: 2026-04-05 - **Last Updated**: 2026-04-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

TORM Logo

TORM - 高性能 .NET ORM 框架

[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![NuGet](https://img.shields.io/nuget/v/TORM.svg)](https://www.nuget.org/packages/TORM) [![.NET](https://img.shields.io/badge/.NET-8.0%20%7C%2010.0-blue.svg)](https://dotnet.microsoft.com/) **轻量级、高性能、功能丰富的对象关系映射框架** **ThinsGateway** 生态系统中的 **ORM** 组件,专为高性能场景设计。
--- ## 中文 ### 📖 项目简介 TORM 是一个为 .NET 平台设计的轻量级、高性能 ORM(对象关系映射)框架。它提供了简洁流畅的 API,支持多种数据库,并针对高性能场景进行了深度优化。 ### ✨ 核心特性 #### 🚀 高性能设计 - **AOT**:支持AOT编译 - **表达式树解析**:高效的 LINQ 表达式到 SQL 转换 - **批量操作优化**:支持 BulkCopy 高性能批量插入/更新 #### 🗄️ 多数据库支持 | 数据库 | 支持状态 | |--------|----------| | MySQL | ✅ 完全支持 | | SQL Server | ✅ 完全支持 | | PostgreSQL | ✅ 完全支持 | | SQLite | ✅ 完全支持 | | TDengine | 暂无映射功能,修改自官方驱动库(原生 + WebSocket),完善AOT支持,可自定义ADO.NET操作 | #### 💡 丰富的功能 **基础 CRUD 操作** **高级功能** - 🔹 **Code First**:自动创建/更新数据库表结构 - 🔹 **分表分库**:支持时间分表、数量分表策略 - 🔹 **批量操作**:BulkCopy 高性能批量导入 - 🔹 **事务管理**:支持同步/异步事务 - 🔹 **AOP 拦截**:SQL 执行前后拦截,日志记录 - 🔹 **JSON 支持**:原生 JSON 类型支持 ### 📊 性能测试 TORM 与国内主流 ORM 框架 的Sqlite性能对比测试结果: ``` BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8037/25H2/2025Update/HudsonValley2) Intel Core Ultra 9 285H 2.90GHz, 1 CPU, 16 logical and 16 physical cores .NET SDK 10.0.103 [Host] : .NET 10.0.3 (10.0.3, 10.0.326.7603), X64 RyuJIT x86-64-v3 .NET 10.0 : .NET 10.0.3 (10.0.3, 10.0.326.7603), X64 RyuJIT x86-64-v3 Job=.NET 10.0 Runtime=.NET 10.0 ``` | Method | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | |--------------------------- |-----------------:|----------------:|----------------:|-----------------:|------:|--------:|------------:|-----------:|----------:|-------------:|------------:| | TORM_BulkInsert_10000 | 29,483.870 μs | 564.6185 μs | 554.5309 μs | 29,662.345 μs | 1.00 | 0.03 | 1062.5000 | - | - | 13392.2 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_BulkInsert_10000 | 54,989.997 μs | 1,048.1157 μs | 1,076.3376 μs | 55,272.167 μs | 1.00 | 0.03 | 2833.3333 | 1000.0000 | 166.6667 | 34263.76 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_BulkInsert_10000 | 537,387.137 μs | 14,137.7720 μs | 41,240.5475 μs | 553,427.500 μs | 1.01 | 0.12 | 5000.0000 | 1000.0000 | - | 64690.97 KB | 1.00 | | | | | | | | | | | | | | | TORM_BulkInsert_50000 | 156,769.159 μs | 1,091.2339 μs | 967.3505 μs | 156,778.888 μs | 1.00 | 0.01 | 5250.0000 | - | - | 66934.26 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_BulkInsert_50000 | 268,856.227 μs | 3,064.4750 μs | 2,866.5118 μs | 269,124.600 μs | 1.00 | 0.01 | 14000.0000 | 4000.0000 | 1000.0000 | 168710.47 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_BulkInsert_50000 | 2,791,199.208 μs | 55,809.9648 μs | 97,746.6592 μs | 2,802,945.200 μs | 1.00 | 0.05 | 26000.0000 | 1000.0000 | - | 323409.88 KB | 1.00 | | | | | | | | | | | | | | | TORM_BulkUpdate_50000 | 99,459.911 μs | 967.6688 μs | 905.1580 μs | 99,733.850 μs | 1.00 | 0.01 | 5333.3333 | - | - | 66933.79 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_BulkUpdate_50000 | 182,485.632 μs | 2,967.7149 μs | 2,630.8020 μs | 182,848.775 μs | 1.00 | 0.02 | 14500.0000 | 4000.0000 | 1500.0000 | 168710.39 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_BulkUpdate_50000 | 2,588,248.118 μs | 51,038.1952 μs | 52,412.4689 μs | 2,598,517.600 μs | 1.00 | 0.03 | 42000.0000 | 1000.0000 | - | 521759.37 KB | 1.00 | | | | | | | | | | | | | | | TORM_DeleteBatch_10000 | 7.996 μs | 0.0541 μs | 0.0480 μs | 8.006 μs | 1.00 | 0.01 | 0.1831 | - | - | 2.4 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_DeleteBatch_10000 | 69.195 μs | 1.0972 μs | 1.0263 μs | 69.525 μs | 1.00 | 0.02 | 0.9155 | - | - | 11.49 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_DeleteBatch_10000 | 65.489 μs | 0.5363 μs | 0.4754 μs | 65.528 μs | 1.00 | 0.01 | 0.5493 | - | - | 7.01 KB | 1.00 | | | | | | | | | | | | | | | TORM_GetList | 9.035 μs | 0.0527 μs | 0.0493 μs | 9.045 μs | 1.00 | 0.01 | 0.5035 | - | - | 6.2 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_GetList | 90.299 μs | 1.7914 μs | 3.6995 μs | 90.835 μs | 1.00 | 0.07 | 2.0752 | 0.9766 | - | 25.61 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_GetList | 66.647 μs | 1.3142 μs | 2.2316 μs | 67.329 μs | 1.00 | 0.05 | 0.8545 | 0.7935 | - | 10.76 KB | 1.00 | | | | | | | | | | | | | | | TORM_InsertBatch_10000 | 29,821.968 μs | 117.4661 μs | 104.1306 μs | 29,839.409 μs | 1.00 | 0.00 | 1062.5000 | - | - | 13391.97 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_InsertBatch_10000 | 119,720.489 μs | 1,983.6632 μs | 1,758.4657 μs | 119,777.158 μs | 1.00 | 0.02 | 6500.0000 | 3166.6667 | 1000.0000 | 72158.74 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_InsertBatch_10000 | 562,874.180 μs | 3,067.5205 μs | 2,869.3606 μs | 562,098.900 μs | 1.00 | 0.01 | 5000.0000 | 1000.0000 | - | 64691.03 KB | 1.00 | | | | | | | | | | | | | | | TORM_InsertBatch_50000 | 156,858.300 μs | 1,981.4147 μs | 1,756.4725 μs | 156,255.650 μs | 1.00 | 0.02 | 5000.0000 | - | - | 66934.18 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_InsertBatch_50000 | 587,029.233 μs | 8,298.3128 μs | 6,478.7768 μs | 587,832.350 μs | 1.00 | 0.02 | 28000.0000 | 13000.0000 | 2000.0000 | 343406.52 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_InsertBatch_50000 | 2,743,381.907 μs | 22,418.0622 μs | 19,873.0282 μs | 2,748,549.050 μs | 1.00 | 0.01 | 26000.0000 | 1000.0000 | - | 323409.86 KB | 1.00 | | | | | | | | | | | | | | | TORM_SaveBatchUpsert_1000 | 2,488.677 μs | 13.5737 μs | 11.3346 μs | 2,487.567 μs | 1.00 | 0.01 | 109.3750 | - | - | 1361.35 KB | 1.00 | | | | | | | | | | | | | | | TORM_SaveBatch_1000 | 3,214.556 μs | 52.0409 μs | 48.6791 μs | 3,198.125 μs | 1.00 | 0.02 | 156.2500 | 15.6250 | - | 2098.54 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_SaveBatch_1000 | 116,875.679 μs | 2,299.9455 μs | 2,361.8747 μs | 116,837.275 μs | 1.00 | 0.03 | 7500.0000 | 1000.0000 | - | 96188.28 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_SaveBatch_1000 | 6,921.216 μs | 136.1796 μs | 127.3824 μs | 6,879.202 μs | 1.00 | 0.03 | 234.3750 | 117.1875 | 70.3125 | 2566.44 KB | 1.00 | | | | | | | | | | | | | | | TORM_SaveBulk_50000 | 130,866.535 μs | 2,607.0517 μs | 7,003.6756 μs | 132,598.750 μs | 1.00 | 0.08 | 5500.0000 | - | - | 67716.66 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_SaveBulk_50000 | 6,335,388.058 μs | 124,308.3524 μs | 170,154.6902 μs | 6,390,547.400 μs | 1.00 | 0.04 | 712000.0000 | 60000.0000 | 9000.0000 | 8634677.2 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_SaveBulk_50000 | 199,689.818 μs | 3,965.4261 μs | 11,184.5554 μs | 202,523.525 μs | 1.00 | 0.08 | 8500.0000 | 2000.0000 | 500.0000 | 129874.98 KB | 1.00 | | | | | | | | | | | | | | | TORM_UpdateBatch_1000 | 2,059.663 μs | 13.8345 μs | 12.9408 μs | 2,055.851 μs | 1.00 | 0.01 | 109.3750 | - | - | 1344.37 KB | 1.00 | | | | | | | | | | | | | | | SqlSugar_UpdateBatch_1000 | 53,523.906 μs | 1,172.7374 μs | 3,364.8036 μs | 54,097.327 μs | 1.01 | 0.11 | 909.0909 | 727.2727 | 181.8182 | 11012.93 KB | 1.00 | | | | | | | | | | | | | | | FreeSql_UpdateBatch_1000 | 53,324.506 μs | 650.2690 μs | 608.2620 μs | 53,067.340 μs | 1.00 | 0.02 | 800.0000 | 200.0000 | - | 10461.04 KB | 1.00 | 可以看出,TORM无论是速度还是内存占用都表现优异,得益于TORM是一个没有任何历史包袱的项目,其高性能设计和批量操作优化,在大数据量场景下表现尤为突出。 > 注:实际性能因数据库类型、数据量、硬件配置等因素会有所不同。建议在实际项目环境中进行测试。 #### 运行性能测试 ```bash cd benchmark/TORM.Benchmark dotnet run -c Release ``` ### 🚀 快速开始 #### 安装 NuGet 包 ```bash dotnet add package TORM ``` #### 基础配置 ```csharp using TORM; // 创建 ORM 客户端 var ormClient = new OrmClient(new OrmConnectionConfig { DatabaseType = OrmDbType.MySql, ConnectionString = "Server=localhost;Database=test;Uid=root;Pwd=password;" }); ``` #### 定义实体 ```csharp [OrmTable(TableName = "users")] public class User { [OrmColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } [OrmColumn(ColumnName = "user_name", Length = 50)] public string Name { get; set; } public int Age { get; set; } public DateTime CreateTime { get; set; } } ``` #### Code First 自动建表 ```csharp // 自动创建表结构 await ormClient.CodeFirst.InitTableAsync(); ``` ### 📚 功能详解 #### 查询操作 ```csharp // 基础查询 var list = await ormClient.Queryable().ToListAsync(); // 条件查询 var adults = await ormClient.Queryable() .Where(u => u.Age >= 18) .ToListAsync(); // 分页查询(返回 PagedList,包含总数) var page = await ormClient.Queryable() .Where(u => u.IsActive) .OrderByDescending(u => u.CreateTime) .ToPageListAsync(pageNumber: 1, pageSize: 20); // 聚合查询 var count = await ormClient.Queryable().CountAsync(); var exists = await ormClient.Queryable().AnyAsync(); // 投影查询 var names = await ormClient.Queryable() .Select(u => new { u.Id, u.Name }) .ToListAsync(); // 流式查询(大数据量场景) await foreach (var user in ormClient.Queryable().ToAsyncEnumerable()) { // 逐行处理 } ``` #### 批量操作 ```csharp // 批量插入(高性能) await ormClient.InsertableRange(users).ExecuteAsync(); // BulkCopy 批量导入(最高性能) await ormClient.BulkCopy().BulkInsertAsync(users); // 批量更新 await ormClient.BulkCopy().BulkUpdateAsync(users); // 批量保存(自动判断插入/更新) await ormClient.BulkCopy().BulkMergeAsync(users); ``` #### 分表操作 **定义分表实体:** ```csharp // 按月分表:表名后缀格式 _yyyyMM [OrmTable(TableName = "logs", SplitType = SplitTableType.Month, SplitColumn = nameof(CreateTime))] public class Log { [OrmColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } public string Message { get; set; } // 分表依据列(必须为 DateTime 类型) public DateTime CreateTime { get; set; } } // 按记录数分表:每 10000 条自动创建新表 [OrmTable(TableName = "sensor_data", MaxRowCount = 10000)] public class SensorData { [OrmColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } public double Value { get; set; } } // 混合策略:按月分表 + 每月内按记录数分表 [OrmTable(TableName = "events", SplitType = SplitTableType.Month, SplitColumn = nameof(EventTime), MaxRowCount = 50000)] public class Event { [OrmColumn(IsPrimaryKey = true, IsIdentity = true)] public long Id { get; set; } public DateTime EventTime { get; set; } } ``` **分表操作示例:** ```csharp // 分表查询(自动跨所有分表查询,可指定时间范围) var list = await ormClient.SplitQueryableAsync( query => query.Where(l => l.Message.Contains("error")), startTime: DateTime.Now.AddDays(-30), endTime: DateTime.Now ); // 分表插入(自动路由到正确的分表) await ormClient.SplitInsertableAsync(logs); // 分表更新 await ormClient.SplitUpdateableAsync(logs, update => update.Set(l => l.Message, "updated")); // 分表删除 await ormClient.SplitDeleteableAsync(logs); ``` **分表类型说明:** | SplitTableType | 说明 | 表名后缀格式 | |----------------|------|-------------| | None | 不分表(默认) | - | | Week | 按周分表 | _yyyyMMdd(周一日期) | | Month | 按月分表 | _yyyyMM | | Quarter | 按季度分表 | _yyyyQn | | Year | 按年分表 | _yyyy | #### 事务管理 ```csharp await db.UseTranAsync(async () => { await db.InsertableRange(addModels).ExecuteAsync().ConfigureAwait(false); }).ConfigureAwait(false); ``` #### AOP 日志拦截 ```csharp // SQL执行前日志 ormClient.Aop.OnLogExecuting = (sql, parameters) => { Console.WriteLine($"执行SQL: {sql}"); }; // SQL执行后日志 ormClient.Aop.OnLogExecuted = (sql, parameters, elapsed) => { Console.WriteLine($"SQL执行耗时: {elapsed.TotalMilliseconds}ms"); }; // 插入/更新前修改值 ormClient.Aop.OnDataExecuting = (args) => { if (args.DataExecutingType == DataExecutingType.Insert) { // 自动填充创建时间 if (args.Entity is BaseEntity entity) { entity.CreateTime = DateTime.Now; } } }; ``` ### 🏗️ 项目结构 ``` TORM/ ├── src/TORM/ # 核心库 │ ├── Ado/ # ADO.NET 基础设施 │ ├── Aop/ # AOP 拦截器 │ ├── Attributes/ # 实体特性 │ ├── BulkCopy/ # 批量操作 │ ├── Client/ # ORM 客户端 │ ├── CodeFirst/ # Code First │ ├── Queryable/ # 查询提供器 │ ├── Insertable/ # 插入提供器 │ ├── Updateable/ # 更新提供器 │ ├── Deletable/ # 删除提供器 │ ├── Saveable/ # 保存提供器 │ ├── SplitTable/ # 分表支持 │ ├── Sql/ # SQL 构建 │ └── TaosData/ # TDengine 支持 │ ├── Driver/ # TDengine 驱动 │ └── TMQ/ # TMQ 消息队列 ├── benchmark/TORM.Benchmark/ # 性能测试 └── test/TORM.Test/ # 单元测试 ``` ### 📄 开源协议 本项目基于 [Apache 2.0](LICENSE) 协议开源。