Core.ORM.Sqlite 2.0.72

There is a newer version of this package available.
See the version list below for details.
dotnet add package Core.ORM.Sqlite --version 2.0.72
                    
NuGet\Install-Package Core.ORM.Sqlite -Version 2.0.72
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Core.ORM.Sqlite" Version="2.0.72" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Core.ORM.Sqlite" Version="2.0.72" />
                    
Directory.Packages.props
<PackageReference Include="Core.ORM.Sqlite" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Core.ORM.Sqlite --version 2.0.72
                    
#r "nuget: Core.ORM.Sqlite, 2.0.72"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Core.ORM.Sqlite@2.0.72
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Core.ORM.Sqlite&version=2.0.72
                    
Install as a Cake Addin
#tool nuget:?package=Core.ORM.Sqlite&version=2.0.72
                    
Install as a Cake Tool

Core.ORM - 高性能 .NET ORM 框架

forked from ThingsGateway/TORM

License NuGet .NET

开始

Nuget安装最新版本。

Install-Package Core.ORM

数据库驱动请按需引用对应的子包:Core.ORM.Sqlite、Core.ORM.MySql、Core.ORM.SqlServer、Core.ORM.PostgreSql、Core.ORM.QuestDb。



TORM - 高性能 .NET ORM 框架

License NuGet .NET

轻量级、高性能、功能丰富的对象关系映射框架

ThingsGateway 生态系统中的 ORM 组件,专为高性能场景设计。

</div>


中文

📖 项目简介

TORM 是一个为 .NET 平台设计的轻量级、高性能数据访问组件。TORM 核心和四个关系型 provider 提供完整 ORM 能力;QuestDB、TDengine 与 Apache IoTDB 扩展包使用各数据库的原生协议,提供 schema、批量写入和查询能力,不伪装成关系型 ORM,也不暴露虚假的事务、Queryable 或 Upsert 语义。

✨ 核心特性

🚀 高性能设计
  • AOT:支持AOT编译
  • 表达式树解析:高效的 LINQ 表达式到 SQL 转换
  • 批量操作优化:支持 BulkCopy 高性能批量插入/更新
🗄️ 多数据库支持
数据库 NuGet/项目 访问模型 当前能力
MySQL / MariaDB TORM.MySql 关系型 ORM CRUD、CodeFirst、事务、分表、BulkCopy、原子 Upsert
SQL Server TORM.SqlServer 关系型 ORM CRUD、CodeFirst、事务、分表、BulkCopy、原子 Upsert
PostgreSQL TORM.PostgreSql 关系型 ORM CRUD、CodeFirst、事务、分表、BulkCopy、原子 Upsert
SQLite TORM.Sqlite 关系型 ORM CRUD、CodeFirst、事务、分表和批量操作
QuestDB TORM.QuestDb 原生 REST SQL + CSV /imp 独立 schema、表维护、TTL、临时 CSV 分批导入、拒绝行与提交状态、原生查询
TDengine TORM.TaosData 显式 Native / WebSocket database、stable、subtable、KEEP、非 ADO row reader、Schemaless 写入结果
Apache IoTDB 2.0.8 TORM.IoTDB Native API Tree / Table 双模型 schema、CodeFirst、Record/Tablet 分批写入、连接池和原生查询

关系型 ORM 与时序原生客户端是明确分层的两组能力。QuestDB、TDengine 和 IoTDB 不注册 IDbProvider,也不支持 OrmClient.Queryable<T>();需要完整 ORM 语义时应使用前四种关系型 provider。

💡 丰富的功能

基础 CRUD 操作

高级功能

  • 🔹 Code First:自动创建/更新数据库表结构
  • 🔹 分表分库:支持时间分表、数量分表策略
  • 🔹 批量操作:BulkCopy 高性能批量导入
  • 🔹 事务管理:支持同步/异步事务
  • 🔹 AOP 拦截:SQL 执行前后拦截,日志记录
  • 🔹 JSON 支持:原生 JSON 类型支持
  • 🔹 全局分表语义:实体更新/删除按分表列路由,Distinct、Count、排序和分页在跨表结果上统一执行
  • 🔹 一致写入列策略:Insertable、Savable 和各关系型 BulkCopy 统一处理 identity 与 IsOnlyIgnoreInsert
  • 🔹 安全 SQL 方言:标识符转义、LIKE 字面量转义和比较方式由 provider 方言配置,不在表达式访问器中硬编码数据库类型
  • 🔹 并发保存:数据库原生 Upsert 保持原子语义,fallback 的存在性查询和写入复用同一连接与事务

⏱️ 时序数据库原生客户端

QuestDB

TORM.QuestDb 保留 QuestDB REST /exec 查询和 /imp 导入协议。每个导入批次使用一个临时 CSV 文件并在成功、拒绝、取消或异常后删除;只有服务端明确接受后才返回 Committed,部分拒绝和全部拒绝都会抛出包含数量与原始响应的异常。

using QuestDbDriver;
using TORM.QuestDb;

using var client = new QuestDbClient(new ConnectionStringBuilder("host=127.0.0.1;port=9000"));
var tables = new QuestDbTableClient(client);
await tables.EnsureTableAsync<SensorRow>();

var writer = new QuestDbCsvBulkWriter<SensorRow>(client) { BatchSize = 1000 };
var result = await writer.WriteAsync(rows);
if (result.CommitState != QuestDbCommitState.Committed)
    throw new InvalidOperationException("QuestDB batch was not committed.");
Apache IoTDB

连接串必须显式指定 Model=treeModel=table。Tree 模型需要 RootPath,Table 模型需要 Database;同一个客户端不会在两种模型之间自动探测或失败回退。

using TORM.IoTDB;

var options = IoTdbConnectionOptions.Parse(
    "DataSource=127.0.0.1;Port=6667;Username=root;Password=root;" +
    "Model=tree;RootPath=root.gateway;PoolSize=2;FetchSize=128;ZoneId=UTC");

await using var client = new IoTdbClient(options);
await client.TreeCodeFirst.InitDeviceSchemaAsync<SensorPoint>("device_1001");
var writer = client.CreateTreeWriter<SensorPoint>("device_1001");
writer.BatchSize = 500;
await writer.InsertAsync(points);

Table 模型使用 IoTdbTableSchemaTableCodeFirstCreateTableWriter<T>();Tree 模型使用 device path、measurement、TreeCodeFirstCreateTreeWriter<T>()。两种模型的查询都返回 IoTdbQueryResult,时间以 UTC 毫秒进入原生协议。

TDengine

TDengine 连接必须显式选择 Protocol=NativeProtocol=WebSocket。当前客户端直接管理 transport 和结果生命周期,不再提供 DbConnectionDbCommandDbDataReaderTaosDataOrmClient 兼容外壳。

using TORM.TaosData;

var options = TdengineConnectionOptions.Parse(
    "Host=127.0.0.1;Port=6041;Username=root;Password=taosdata;Protocol=WebSocket");
using var client = new TdengineClient(options);
if (!client.CheckHealth()) throw new InvalidOperationException("TDengine is unavailable.");

var schema = new TdengineSchemaClient(client);
schema.EnsureDatabase("telemetry");
using var reader = client.Query("SELECT server_version() AS version");

Native/WebSocket 的真实异步和取消能力由 client.Capabilities 明确报告;客户端不会用 Task.Run 伪造异步,也不会在协议失败时自动切换 transport。

📊 性能测试

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是一个没有任何历史包袱的项目,其高性能设计和批量操作优化,在大数据量场景下表现尤为突出。

注:实际性能因数据库类型、数据量、硬件配置等因素会有所不同。建议在实际项目环境中进行测试。

项目结构

TORM/
|-- analyzer/TORM.Generators/     源生成器
|-- src/TORM/                     ORM 核心
|-- src/TORM.Sqlite/              SQLite 驱动
|-- src/TORM.MySql/               MySQL/MariaDB 驱动
|-- src/TORM.SqlServer/           SQL Server 驱动
|-- src/TORM.PostgreSql/          PostgreSQL 驱动
|-- src/TORM.QuestDb/             QuestDB REST SQL、schema 与 CSV writer
|-- src/TORM.IoTDB/               Apache IoTDB Native API Tree/Table 双模型扩展
|-- src/TORM.TaosData/            TDengine Native/WebSocket 原生客户端
|-- samples/TORM.AotDemo/         AOT 示例
|-- benchmark/TORM.Benchmark/     BenchmarkDotNet 基准项目
`-- test/TORM.Test/               自动化测试

构建与测试

dotnet restore TORM.slnx
dotnet build TORM.slnx -c Release
dotnet test test/TORM.Test/TORM.Test.csproj -c Release

真实数据库集成测试使用 SQLite 加六个 Docker 服务:MySQL、PostgreSQL、SQL Server、QuestDB、TDengine 和 Apache IoTDB 2.0.8。固定镜像、端口、账号和连接串保存在 test/TORM.Test/docker-compose.ymltest/TORM.Test/docker-test.env

docker compose -f test/TORM.Test/docker-compose.yml up -d
docker compose -f test/TORM.Test/docker-compose.yml ps
dotnet test test/TORM.Test/TORM.Test.csproj --configuration Release

完整连接变量和 Windows Docker Desktop 注意事项见 数据库集成测试说明,当前生产变更与测试名称的逐项映射见 测试覆盖矩阵

2026-08-30 的完整 Release 实测结果为 3808/3808 通过、0 失败、0 跳过;测试覆盖四种关系型 provider 的真实 CRUD/事务/分表/索引/BulkCopy,以及 QuestDB、TDengine、IoTDB 的真实原生协议闭环。

运行基准测试:

dotnet run -c Release --project benchmark/TORM.Benchmark/TORM.Benchmark.csproj
基础配置
using TORM;

// 创建 ORM 客户端
using var ormClient = new OrmClient(new OrmConnectionConfig
{
    DatabaseType = OrmDbType.MySql,
    ConnectionString = "Server=localhost;Database=test;Uid=root;Pwd=password;"
});
定义实体
[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 自动建表
// 自动创建表结构
await ormClient.CodeFirst.InitTableAsync<User>();

📚 功能详解

查询操作
// 基础查询
var list = await ormClient.Queryable<User>().ToListAsync();

// 条件查询
var adults = await ormClient.Queryable<User>()
    .Where(u => u.Age >= 18)
    .ToListAsync();

// 分页查询(返回 PagedList<T>,包含总数)
var page = await ormClient.Queryable<User>()
    .Where(u => u.IsActive)
    .OrderByDescending(u => u.CreateTime)
    .ToPageListAsync(pageNumber: 1, pageSize: 20);

// 聚合查询
var count = await ormClient.Queryable<User>().CountAsync();
var exists = await ormClient.Queryable<User>().AnyAsync();

// 投影查询
var names = await ormClient.Queryable<User>()
    .Select(u => new { u.Id, u.Name })
    .ToListAsync();

// 流式查询(大数据量场景)
await foreach (var user in ormClient.Queryable<User>().ToAsyncEnumerable())
{
    // 逐行处理
}
批量操作
// 批量插入(高性能)
await ormClient.InsertableRange(users).ExecuteAsync();

// BulkCopy 批量导入(最高性能)
await ormClient.BulkCopy<User>().BulkInsertAsync(users);

// 批量更新
await ormClient.BulkCopy<User>().BulkUpdateAsync(users);

// 批量保存(自动判断插入/更新)
await ormClient.BulkCopy<User>().BulkMergeAsync(users);
分表操作

定义分表实体:

// 按月分表:表名后缀格式 _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; }
}

分表操作示例:

// 分表查询(自动跨所有分表查询,可指定时间范围)
var list = await ormClient.SplitQueryableAsync<Log>(
    query => query.Where(l => l.Message.Contains("error")),
    startTime: DateTime.Now.AddDays(-30),
    endTime: DateTime.Now
);

// 分表插入(自动路由到正确的分表)
await ormClient.SplitInsertableAsync(logs);

// 分表更新
await ormClient.SplitUpdatableAsync(logs, update => update.Set(l => l.Message, "updated"));

// 分表删除
await ormClient.SplitDeletableAsync(logs);

分表类型说明:

SplitTableType 说明 表名后缀格式
None 不分表(默认) -
Week 按周分表 _yyyyMMdd(周一日期)
Month 按月分表 _yyyyMM
Quarter 按季度分表 _yyyyQn
Year 按年分表 _yyyy
事务管理
await ormClient.UseTranAsync(async () =>
{
    await ormClient.InsertableRange(addModels).ExecuteAsync().ConfigureAwait(false);
}).ConfigureAwait(false);
AOP 日志拦截
// 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;
        }
    }
};

Release 构建会生成 NuGet 包并输出到上级 nupkgs 目录。

相关资源

许可证

本项目使用 Apache-2.0 协议。

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.74 76 9/21/2026
2.0.73 82 9/18/2026
2.0.72 81 9/14/2026
2.0.71 98 9/3/2026
2.0.69 102 9/1/2026
2.0.68 96 8/31/2026
2.0.63 92 8/26/2026
2.0.62 106 8/22/2026
2.0.59 106 8/11/2026
2.0.58 119 8/9/2026
2.0.56 114 8/1/2026
2.0.55.6 116 7/24/2026
2.0.55.5 117 7/22/2026
2.0.55.4 120 7/22/2026
2.0.55.3 109 7/21/2026
2.0.55.2 117 7/21/2026
2.0.55.1 98 7/18/2026
2.0.55 106 7/18/2026
2.0.54 120 7/13/2026
2.0.53 112 7/13/2026
Loading failed