Skip to content

feat: complete SonnetDB 3.1 provider support - #2234

Draft
maikebing wants to merge 7 commits into
dotnetcore:masterfrom
IoTSharp:master
Draft

maikebing wants to merge 7 commits into
dotnetcore:masterfrom
IoTSharp:master

Conversation

@maikebing

@maikebing maikebing commented Apr 29, 2026 •

Copy link
Copy Markdown

变更内容

本 PR 完成 SonnetDB 3.1.0 的 FreeSql 提供程序实现,并把关系表与时序测量的能力边界落实到 SQL 生成、执行、CodeFirst、DbFirst 和类型转换层。

  • 增加 [SonnetDBTable] 关系表模型,保留未标记实体的时序测量兼容路径。
  • 完成关系表的 CodeFirst/DbFirst、主键、自增、ROWVERSION 乐观并发、索引、事务、参数化 CRUD、JOIN 和 INSERT ... RETURNING。
  • 完成时序测量的 TAG/FIELD、时间转换、VECTOR、GEOPOINT、JSON、窗口函数、表值函数和批量写入支持。
  • 增加 System.Text.Json DOM、GEOPOINT、VECTOR 的读写处理器,以及 JsonMap 的 SonnetDB JSON 列映射。
  • 增加安全的 CodeFirst 差异迁移、限定名解析、视图读取、JSON 路径索引元数据和 SonnetDB 兼容性文档。
  • 对 SonnetDB 3.1 不支持的 UPSERT、INSERT ... SELECT、递归 CTE、FOR UPDATE、UPDATE JOIN、UNION ALL、位运算、部分日期/字符串/数学函数、关系表 VECTOR/GEOPOINT 等操作,在生成或发送 SQL 前给出明确的 NotSupportedException。

审查修复

  • 恢复 Utils.GetDataReaderValueBlockExpression(Type, Expression) 原公开二参数签名,避免已有二进制调用方出现 MissingMethodException;方言读取转换使用新增内部重载。
  • 修正 CodeFirst 默认值比较,字符串默认值的大小写和连续空格变化现在会生成迁移 DDL。
  • 修正时序测量 Delete.ExecuteAffrows(),先统计匹配测量行再执行删除,避免将 SonnetDB 墓碑数量误报为删除行数。
  • 删除无效的 DbFirst ROWVERSION 反射探测和构建生成的无关 XML 文档噪音;保留必要的 API 文档条目。
  • 核对分表批处理、参数转义、TVF 标识符校验、全局读取器注册和公共层其他提供程序兼容性,未发现仍会静默产生错误 SQL 的致命缺陷。

验证

  • dotnet test FreeSql.Tests/FreeSql.Tests.Provider.SonnetDB/FreeSql.Tests.Provider.SonnetDB.csproj --no-restore -p:GenerateDocumentationFile=false
    • 163 passed, 0 failed。
  • dotnet build FreeSql/FreeSql.csproj --no-restore
    • netstandard2.0、netstandard2.1、net40、net45、net451 全部通过,0 warnings、0 errors。
  • dotnet build Providers/FreeSql.Provider.SonnetDB/FreeSql.Provider.SonnetDB.csproj --no-restore
    • net10.0 通过,0 warnings、0 errors。

SonnetDB 3.1.0 的已验证能力缺口、复现 SQL 和上游问题单见 docs/sonnetdb-gap-issue.md。

SonnetDB 上游依赖与进展跟踪

FreeSql 当前按 SonnetDB 3.1.0 已发布合同实现;下列能力仍需要 SonnetDB 上游补齐后,才能移除提供程序中的兼容性门禁。链接直接指向 SonnetDB Issue,打开后可查看最新状态;截至 2026-09-20,这些依赖项均为 open。

上游 PR 状态

  • 当前没有针对上述 SQL、DDL 或 ADO.NET 能力的 SonnetDB 实现 PR;

SonnetDB 当前 open 的

  • #164
  • #170 仅是 Dependabot 依赖升级,不改变这些数据库合同。
  • 已合并且被当前 Provider 使用的基础能力:
  • SonnetDB PR #37(向量距离与 centroid 聚合)
  • #46(KNN 表值函数)
  • #142(USearch 过滤检索)
  • #157(RAG 检索融合)。

RETURNING/ON CONFLICT 的实验提交 d664ead6 尚未作为 SonnetDB 3.1.0 发布能力,仍由 IoTSharp/SonnetDB#184 跟踪;FreeSql 当前继续按已发布合同拒绝原子 UPSERT。

GitHub 当前不支持把不同仓库的 Issue 作为 FreeSql PR 的原生 blocked by 依赖卡片,因此这里保留了可点击的跨仓库引用;上游 Issue/PR 状态变化后,从这些链接即可直接查看最新进展。

实现了 SonnetDBCodeFirst,用于代码优先的数据库操作。

实现了 SonnetDBDbFirst,用于数据库优先的操作,包括表和列的元数据检索。

创建了 SonnetDBExpression,用于处理表达式到 SQL 的转换。

添加了用于 SonnetDB 格式化的全局扩展方法。

开发了 SonnetDBProvider,用于管理数据库连接和 CRUD 操作。

引入了 SonnetDBUtils,提供参数处理和 SQL 格式化相关的实用函数。

添加了 key.snk,用于为程序集赋予强名称。
Copilot AI review requested due to automatic review settings April 29, 2026 17:20
@maikebing
maikebing marked this pull request as draft April 29, 2026 17:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 为 FreeSql 新增 SonnetDB Provider,实现 SonnetDB 的 ADO、表达式到 SQL 的转换,以及 CodeFirst/DbFirst 的基础能力,并把它接入到 FreeSqlBuilder/Ado.NET 扩展与解决方案文件中。

Changes:

  • 新增 FreeSql.Provider.SonnetDB 项目:Ado/Utils/Expression、CodeFirst/DbFirst、Select/Insert/Delete、以及 TAG/FIELD 属性标注。
  • 将 SonnetDB 集成到 FreeSqlBuilder、AdoNetExtensions 自动识别,以及 DataType 枚举。
  • 更新 FreeSql.sln 与 FreeSql-lite.sln 以包含新 Provider 项目,并引入强命名 key。

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Providers/FreeSql.Provider.SonnetDB/key.snk SonnetDB provider 强命名密钥文件
Providers/FreeSql.Provider.SonnetDB/FreeSql.Provider.SonnetDB.csproj 新 Provider 项目配置与 SonnetDB 依赖
Providers/FreeSql.Provider.SonnetDB/SonnetDBProvider.cs Provider 入口:创建各类 CRUD Provider、初始化 Ado/CodeFirst/DbFirst
Providers/FreeSql.Provider.SonnetDB/SonnetDBAdo/SonnetDBAdo.cs SonnetDB ADO.NET 封装:连接池、参数转义与命令创建
Providers/FreeSql.Provider.SonnetDB/SonnetDBUtils.cs CommonUtils 适配:参数、SQL 引号、常量格式化等
Providers/FreeSql.Provider.SonnetDB/SonnetDBExpression.cs Expression → SQL 适配实现
Providers/FreeSql.Provider.SonnetDB/SonnetDBCodeFirst.cs CodeFirst:类型映射与测量表(measurement)DDL 生成
Providers/FreeSql.Provider.SonnetDB/SonnetDBDbFirst.cs DbFirst:表/列元数据检索与类型映射
Providers/FreeSql.Provider.SonnetDB/SonnetDBGlobalExtensions.cs SonnetDB 专用 FormatSonnetDB 全局扩展
Providers/FreeSql.Provider.SonnetDB/Curd/SonnetDBSelect.cs SELECT 生成(含 alias 去除与 count/limit/offset 适配)
Providers/FreeSql.Provider.SonnetDB/Curd/SonnetDBInsert.cs INSERT 执行与 AOP 事件触发
Providers/FreeSql.Provider.SonnetDB/Curd/SonnetDBDelete.cs DELETE 执行(含计数补偿逻辑)
Providers/FreeSql.Provider.SonnetDB/Attributes/SonnetDBTagAttribute.cs TAG 标记属性
Providers/FreeSql.Provider.SonnetDB/Attributes/SonnetDBFieldAttribute.cs FIELD 标记属性
FreeSql/FreeSqlBuilder.cs 新增 DataType.SonnetDB 的 Build 分支
FreeSql/Extensions/AdoNetExtensions.cs ADO.NET 连接类型识别新增 SndbConnection
FreeSql/DataType.cs 枚举新增 SonnetDB
FreeSql.sln 解决方案加入 SonnetDB provider 项目
FreeSql-lite.sln lite 解决方案加入 SonnetDB provider 项目

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread FreeSql/FreeSqlBuilder.cs
Comment on lines +393 to +396
case DataType.SonnetDB:
type = Type.GetType("FreeSql.SonnetDB.SonnetDBProvider`1,FreeSql.Provider.SonnetDB")?.MakeGenericType(typeof(TMark));
if (type == null) throwNotFind("FreeSql.Provider.SonnetDB.dll", "FreeSql.SonnetDB.SonnetDBProvider<>");
break;
Comment on lines +31 to +46
long ret = 0;
Exception exception = null;
try
{
_orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params);
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
}
Comment on lines +65 to +80
long ret = 0;
Exception exception = null;
try
{
await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken);
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.CurdAfterEventArgs(before, exception, ret);
_orm.Aop.CurdAfterHandler?.Invoke(this, after);
}
Comment on lines +132 to +137
foreach (var alias in tables.Select(a => a.Alias).Where(a => string.IsNullOrEmpty(a) == false).Distinct().OrderByDescending(a => a.Length))
{
var escapedAlias = Regex.Escape(alias);
sql = Regex.Replace(sql, $@"\b{escapedAlias}\.", "", RegexOptions.IgnoreCase);
sql = Regex.Replace(sql, $@"(\bFROM\s+(?:""[^""]+""|\w+))\s+{escapedAlias}\b", "$1", RegexOptions.IgnoreCase);
sql = Regex.Replace(sql, $@"(\bJOIN\s+(?:""[^""]+""|\w+))\s+{escapedAlias}\b", "$1", RegexOptions.IgnoreCase);
Comment on lines +18 to +25
public override IUpdate<T1> CreateUpdateProvider<T1>(object dywhere) =>
throw new NotImplementedException($"FreeSql.Provider.SonnetDB {CoreErrorStrings.S_Not_Implemented_Feature}");

public override IDelete<T1> CreateDeleteProvider<T1>(object dywhere) =>
new SonnetDBDelete<T1>(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere);

public override IInsertOrUpdate<T1> CreateInsertOrUpdateProvider<T1>() =>
throw new NotImplementedException($"FreeSql.Provider.SonnetDB {CoreErrorStrings.S_Not_Implemented_Feature}");
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net10.0</TargetFrameworks>
@2881099

2881099 commented Apr 30, 2026

Copy link
Copy Markdown
Collaborator

Excellent,完成之后通知一下,这边合并发布版本

- Implemented FormatSonnetDB extension method for safe SQL string formatting to prevent SQL injection.
- Enhanced SonnetDBUtils with various utility functions for SQL parameter binding, identifier quoting, null value handling, string concatenation, and current time retrieval.
- Introduced SonnetDBFunctions class containing proprietary SQL functions for FreeSql, including PID control, time series analysis, statistical aggregations, anomaly detection, and geospatial functions.
- Added comprehensive documentation for each function to facilitate usage and understanding.
@maikebing
maikebing marked this pull request as ready for review May 6, 2026 17:38
@maikebing

Copy link
Copy Markdown
Author

已经完成。 @2881099

@maikebing
maikebing marked this pull request as draft July 8, 2026 02:09
Add relationship-table and measurement mappings, capability guards, type handlers, DbFirst/CodeFirst support, and comprehensive SonnetDB coverage.
@maikebing maikebing changed the title 添加 SonnetDB 提供程序实现 feat: complete SonnetDB 3.1 provider support Sep 20, 2026
@2881099

2881099 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

FreeSql 的代码是必须合并的吗?我担心会有其他 bug,最理想的状态是只在不变。

@maikebing

Copy link
Copy Markdown
Author

FreeSql 的代码是必须合并的吗?我担心会有其他 bug,最理想的状态是只在不变。

我尽可能的少该freesql ,让我琢磨琢磨。 尽可能的影响少

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants