Sqlx 0.6.5
See the version list below for details.
dotnet add package Sqlx --version 0.6.5
NuGet\Install-Package Sqlx -Version 0.6.5
<PackageReference Include="Sqlx" Version="0.6.5" />
<PackageVersion Include="Sqlx" Version="0.6.5" />
<PackageReference Include="Sqlx" />
paket add Sqlx --version 0.6.5
#r "nuget: Sqlx, 0.6.5"
#:package Sqlx@0.6.5
#addin nuget:?package=Sqlx&version=0.6.5
#tool nuget:?package=Sqlx&version=0.6.5
Sqlx
高性能、AOT 友好的 .NET 数据库访问库。使用源生成器在编译时生成代码,零运行时反射,完全支持 Native AOT。
核心特性
- 🚀 高性能 - 比 Dapper.AOT 快 1.5-2.9%,最低 GC 压力(Gen1 GC 是 FreeSql 的 1/13)
- ⚡ 零反射 - 编译时源生成,运行时无反射开销
- 🎯 类型安全 - 编译时验证 SQL 模板和表达式
- 🌐 多数据库 - SQLite、PostgreSQL、MySQL、SQL Server、Oracle、DB2
- 📦 AOT 就绪 - 完全支持 Native AOT,通过 1564 个单元测试
- 🔧 LINQ 支持 - IQueryable 接口,支持 Where/Select/OrderBy/Join 等
- 💾 智能缓存 - SqlQuery<T> 泛型缓存,自动注册 EntityProvider
- 🔍 自动发现 - 源生成器自动发现 SqlQuery<T> 和 SqlTemplate 中的实体类型
快速开始
dotnet add package Sqlx
// 1. 定义实体
[Sqlx, TableName("users")]
public class User
{
[Key] public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
// 2. 定义仓储接口
public interface IUserRepository : ICrudRepository<User, long>
{
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE age >= @minAge")]
Task<List<User>> GetAdultsAsync(int minAge);
}
// 3. 实现仓储(代码自动生成)
[SqlDefine(SqlDefineTypes.SQLite)]
[RepositoryFor(typeof(IUserRepository))]
public partial class UserRepository(DbConnection connection) : IUserRepository { }
// 4. 使用
await using var conn = new SqliteConnection("Data Source=app.db");
var repo = new UserRepository(conn);
var adults = await repo.GetAdultsAsync(18);
重要说明: Sqlx 中有两个不同的 SqlTemplate:
[SqlTemplate]特性 (Sqlx.Annotations) - 用于标注接口方法,定义 SQL 模板SqlTemplate类 (Sqlx) - 运行时类,用于调试查看生成的 SQL
using Sqlx; // SqlTemplate 类
using Sqlx.Annotations; // [SqlTemplate] 特性
public interface IUserRepository
{
// [SqlTemplate] 特性 - 标注方法执行查询
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE id = @id")]
Task<User?> GetByIdAsync(long id);
// SqlTemplate 类 - 返回类型用于调试(不执行查询)
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE id = @id")]
SqlTemplate GetByIdSql(long id);
}
// 调试使用
var template = repo.GetByIdSql(123);
Console.WriteLine($"SQL: {template.Sql}");
SQL 模板占位符
占位符自动适配不同数据库方言:
| 占位符 | 说明 | 示例输出 |
|---|---|---|
{{table}} |
表名(带方言引号) | "users" (PostgreSQL) |
{{columns}} |
所有列名 | id, name, age |
{{columns --exclude Id}} |
排除指定列 | name, age |
{{values --exclude Id}} |
参数占位符 | @name, @age |
{{values --inline CreatedAt=CURRENT_TIMESTAMP}} |
内联表达式(INSERT 默认值) | @name, @age, CURRENT_TIMESTAMP |
{{set --exclude Id}} |
UPDATE SET 子句 | name = @name |
{{set --inline Version=Version+1}} |
内联表达式(UPDATE 计算字段) | name = @name, version = version+1 |
{{where --object filter}} |
对象条件查询 | (name = @name AND age = @age) |
{{if notnull=param}}...{{/if}} |
条件包含 | 动态 SQL |
内联表达式(Inline Expressions)
内联表达式允许在 SQL 中使用表达式、函数和字面量:
// UPDATE 示例:自动递增版本号
[SqlTemplate(@"
UPDATE {{table}}
SET {{set --exclude Id,Version --inline Version=Version+1,UpdatedAt=CURRENT_TIMESTAMP}}
WHERE id = @id
")]
Task<int> UpdateAsync(long id, string name, string email);
// 生成: UPDATE [users] SET [name] = @name, [email] = @email,
// [version] = [version]+1, [updated_at] = CURRENT_TIMESTAMP WHERE id = @id
// INSERT 示例:设置默认值
[SqlTemplate(@"
INSERT INTO {{table}} ({{columns --exclude Id}})
VALUES ({{values --exclude Id --inline Status='pending',CreatedAt=CURRENT_TIMESTAMP}})
")]
Task<int> CreateAsync(string name, string description);
// 生成: INSERT INTO [tasks] ([name], [description], [status], [created_at])
// VALUES (@name, @description, 'pending', CURRENT_TIMESTAMP)
支持的表达式:
- 算术运算:
Version=Version+1,Total=@quantity*@unitPrice - SQL 函数:
CreatedAt=CURRENT_TIMESTAMP,Email=LOWER(TRIM(Email)) - 字面量:
Status='pending',Priority=0,IsActive=1 - 复杂表达式:
Result=COALESCE(NULLIF(Value,''),Default)
关键特性:
- ✅ 使用属性名(PascalCase),自动转换为列名
- ✅ 函数内的逗号被正确处理(如
COALESCE(Status,'pending')) - ✅ 支持嵌套函数和深度括号
- ✅ 跨数据库方言自动适配
- ✅ 编译时解析,零运行时开销
各数据库生成的 SQL:
| 数据库 | 生成的 SQL |
|---|---|
| SQLite | SELECT [id], [name] FROM [users] WHERE is_active = 1 |
| PostgreSQL | SELECT "id", "name" FROM "users" WHERE is_active = true |
| MySQL | SELECT `id`, `name` FROM `users` WHERE is_active = 1 |
内置仓储接口
继承 ICrudRepository<TEntity, TKey> 获得 42 个标准方法(24 个查询 + 18 个命令):
查询方法(24 个):
- 单实体查询:
GetByIdAsync/GetById,GetFirstWhereAsync/GetFirstWhere - 列表查询:
GetByIdsAsync/GetByIds,GetAllAsync/GetAll,GetWhereAsync/GetWhere - 分页查询:
GetPagedAsync/GetPaged,GetPagedWhereAsync/GetPagedWhere - 存在性检查:
ExistsByIdAsync/ExistsById,ExistsAsync/Exists - 计数:
CountAsync/Count,CountWhereAsync/CountWhere
命令方法(18 个):
- 插入:
InsertAndGetIdAsync/InsertAndGetId,InsertAsync/Insert,BatchInsertAsync/BatchInsert - 更新:
UpdateAsync/Update,UpdateWhereAsync/UpdateWhere,BatchUpdateAsync/BatchUpdate - 删除:
DeleteAsync/Delete,DeleteByIdsAsync/DeleteByIds,DeleteWhereAsync/DeleteWhere,DeleteAllAsync/DeleteAll
public interface IUserRepository : ICrudRepository<User, long>
{
// 继承 42 个标准方法,无需自定义即可使用
// 自定义方法(仅在需要复杂查询时)
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE name LIKE @pattern")]
Task<List<User>> SearchByNameAsync(string pattern);
}
条件占位符
// 动态搜索:只在参数有值时添加条件
[SqlTemplate(@"
SELECT {{columns}} FROM {{table}} WHERE 1=1
{{if notnull=name}}AND name LIKE @name{{/if}}
{{if notnull=minAge}}AND age >= @minAge{{/if}}
")]
Task<List<User>> SearchAsync(string? name, int? minAge);
对象条件查询
使用 {{where --object}} 从字典自动生成 WHERE 条件(AOT 兼容):
// 定义查询方法
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE {{where --object filter}}")]
Task<List<User>> FilterAsync(IReadOnlyDictionary<string, object?> filter);
// 使用:只有非空值会生成条件
var filter = new Dictionary<string, object?>
{
["Name"] = "John", // 生成: [name] = @name
["Age"] = 25, // 生成: [age] = @age
["Email"] = null // 忽略(null 值)
};
var users = await repo.FilterAsync(filter);
// 生成: SELECT ... WHERE ([name] = @name AND [age] = @age)
// 空字典返回 1=1(查询所有)
var all = await repo.FilterAsync(new Dictionary<string, object?>());
// 生成: SELECT ... WHERE 1=1
IQueryable 查询构建器
使用标准 LINQ 语法构建类型安全的 SQL 查询:
// 基本查询
var query = SqlQuery<User>.ForSqlite()
.Where(u => u.Age >= 18 && u.IsActive)
.OrderBy(u => u.Name)
.Take(10);
var sql = query.ToSql();
// SELECT [id], [name], [age], [is_active] FROM [User]
// WHERE ([age] >= 18 AND [is_active] = 1)
// ORDER BY [name] ASC LIMIT 10
// 投影查询(匿名类型,完全 AOT 兼容)
var results = await SqlQuery<User>.ForPostgreSQL()
.Where(u => u.Name.Contains("test"))
.Select(u => new { u.Id, u.Name })
.WithConnection(connection)
.ToListAsync();
// JOIN 查询
var query = SqlQuery<User>.ForSqlite()
.Join(SqlQuery<Order>.ForSqlite(),
u => u.Id,
o => o.UserId,
(u, o) => new { u.Name, o.Total })
.Where(x => x.Total > 100);
// 聚合函数
var maxAge = await SqlQuery<User>.ForSqlite()
.WithConnection(connection)
.WithReader(UserResultReader.Default)
.MaxAsync(u => u.Age);
支持的 LINQ 方法:
Where,Select,OrderBy,ThenBy,Take,SkipGroupBy,Distinct,Join,GroupJoinCount,Min,Max,Sum,AverageFirst,FirstOrDefault,Any
支持的函数:
- String:
Contains,StartsWith,EndsWith,ToUpper,ToLower,Trim,Substring,Replace,Length - Math:
Abs,Round,Floor,Ceiling,Sqrt,Pow,Min,Max
表达式查询(仓储模式)
// 在仓储中使用 LINQ 表达式
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE {{where --param predicate}}")]
Task<List<User>> GetWhereAsync(Expression<Func<User, bool>> predicate);
// 使用
var adults = await repo.GetWhereAsync(u => u.Age >= 18 && u.IsActive);
批量执行
var users = new List<User> { new() { Name = "Alice" }, new() { Name = "Bob" } };
var sql = "INSERT INTO users (name) VALUES (@name)";
await connection.ExecuteBatchAsync(sql, users, UserParameterBinder.Default);
连接和事务管理
连接获取优先级
源生成器按以下优先级查找 DbConnection:
方法参数 > 字段 > 属性 > 主构造函数
// 方式 1: 显式字段(推荐,优先级最高)
[SqlDefine(SqlDefineTypes.SQLite)]
[RepositoryFor(typeof(IUserRepository))]
public partial class UserRepository : IUserRepository
{
private readonly SqliteConnection _connection;
public DbTransaction? Transaction { get; set; }
public UserRepository(SqliteConnection connection)
{
_connection = connection;
}
}
// 方式 2: 属性(适合需要外部访问)
public partial class UserRepository : IUserRepository
{
public SqliteConnection Connection { get; }
public DbTransaction? Transaction { get; set; }
public UserRepository(SqliteConnection connection)
{
Connection = connection;
}
}
// 方式 3: 主构造函数(最简洁,自动生成)
public partial class UserRepository(SqliteConnection connection) : IUserRepository
{
// 生成器自动生成:
// private readonly SqliteConnection _connection = connection;
// public DbTransaction? Transaction { get; set; }
}
// 方式 4: 方法参数(最灵活,优先级最高)
public interface IUserRepository
{
// 使用类级别连接
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE id = @id")]
Task<User?> GetByIdAsync(long id);
// 使用方法参数连接(覆盖类级别连接)
[SqlTemplate("SELECT {{columns}} FROM {{table}} WHERE id = @id")]
Task<User?> GetByIdWithConnectionAsync(DbConnection connection, long id);
}
事务支持
var repo = new UserRepository(connection);
using var transaction = connection.BeginTransaction();
repo.Transaction = transaction;
try
{
await repo.InsertAsync(user1);
await repo.UpdateAsync(user2);
await repo.DeleteAsync(user3);
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
自动生成规则:
- 如果用户未定义
Transaction属性,生成器会自动生成 - 如果用户未定义连接字段/属性,生成器会从主构造函数参数自动生成字段
性能对比
基于 BenchmarkDotNet 测试(.NET 10 LTS,SQLite 内存数据库):
小数据集性能(10-100条)- Web API 主要场景
| 数据量 | Sqlx | Dapper.AOT | FreeSql | Sqlx 优势 |
|---|---|---|---|---|
| 10条 | 42.19 μs | 43.42 μs | 49.64 μs | 🥇 快 2.9% / 17.7% |
| 100条 | 230.35 μs | 233.76 μs | 237.38 μs | 🥇 快 1.5% / 3.1% |
| 1000条 | 2,165.87 μs | 2,172.08 μs | 1,625.41 μs | 🥇 快 0.3% |
内存效率
| 数据量 | Sqlx | Dapper.AOT | FreeSql | Sqlx 优势 |
|---|---|---|---|---|
| 10条 | 4.68 KB | 6.55 KB | 8.67 KB | 🥇 少 40% / 85% |
| 100条 | 37 KB | 45.66 KB | 37.23 KB | 🥇 少 23% |
| 1000条 | 360.24 KB | 432.38 KB | 318.6 KB | 🥇 少 20% |
GC 压力(关键指标)
| 数据量 | Sqlx Gen1 | Dapper.AOT Gen1 | FreeSql Gen1 | Sqlx 优势 |
|---|---|---|---|---|
| 1000条 | 1.95 | 3.91 | 25.39 | 🥇 最低(FreeSql 的 1/13) |
关键洞察:
- ✅ Sqlx 在小数据集(10-100条)上性能最优,这是 Web API 的主要场景
- ✅ Sqlx 的 GC 压力最小,更适合长时间运行的应用
- ✅ Sqlx 在所有场景下都比 Dapper.AOT 快,且内存效率更高
- ⚠️ FreeSql 在大数据集(1000+条)上更快,但 Gen1 GC 是 Sqlx 的 13倍
支持的数据库
| 数据库 | 方言枚举 | 状态 |
|---|---|---|
| SQLite | SqlDefineTypes.SQLite |
✅ 完全支持 |
| PostgreSQL | SqlDefineTypes.PostgreSql |
✅ 完全支持 |
| MySQL | SqlDefineTypes.MySql |
✅ 完全支持 |
| SQL Server | SqlDefineTypes.SqlServer |
✅ 完全支持 |
| Oracle | SqlDefineTypes.Oracle |
✅ 完全支持 |
| IBM DB2 | SqlDefineTypes.DB2 |
✅ 完全支持 |
推荐: .NET 10 (LTS) - 支持到 2028 年 11 月,性能最佳
更多文档
许可证
MIT License - 详见 LICENSE.txt
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
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 |
|---|---|---|
| 0.6.8 | 96 | 2/7/2026 |
| 0.6.7 | 81 | 2/5/2026 |
| 0.6.6 | 80 | 2/3/2026 |
| 0.6.5 | 97 | 1/23/2026 |
| 0.6.4 | 87 | 1/22/2026 |
| 0.6.3 | 86 | 1/22/2026 |
| 0.6.2 | 99 | 1/16/2026 |
| 0.6.1 | 84 | 1/15/2026 |
| 0.6.0 | 83 | 1/15/2026 |
| 0.5.0 | 107 | 1/11/2026 |
| 0.4.0 | 213 | 10/27/2025 |
| 0.3.0 | 284 | 10/2/2025 |
| 0.2.0 | 227 | 9/21/2025 |
| 0.1.4-dev | 210 | 8/31/2025 |
| 0.1.3-dev | 118 | 8/23/2025 |
| 0.1.2-dev | 177 | 8/20/2025 |
| 0.1.1-dev | 149 | 8/17/2025 |
| 0.1.0-dev | 164 | 7/27/2025 |