SmartDapper 1.1.1
See the version list below for details.
dotnet add package SmartDapper --version 1.1.1
NuGet\Install-Package SmartDapper -Version 1.1.1
<PackageReference Include="SmartDapper" Version="1.1.1" />
<PackageVersion Include="SmartDapper" Version="1.1.1" />
<PackageReference Include="SmartDapper" />
paket add SmartDapper --version 1.1.1
#r "nuget: SmartDapper, 1.1.1"
#:package SmartDapper@1.1.1
#addin nuget:?package=SmartDapper&version=1.1.1
#tool nuget:?package=SmartDapper&version=1.1.1
SmartDapper
SmartDapper 是一个基于 Dapper 的轻量级扩展库,提供 表达式树转 SQL、通用 CRUD、分页查询 与 多数据库适配(SQL Server / MySQL / SQLite)。默认参数化执行,以降低 SQL 注入风险。
安装
dotnet add package SmartDapper
快速开始(SQL 生成 + Dapper 执行)
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Dapper;
using Microsoft.Data.SqlClient;
using SmartDapper.SqlGenerator;
[Table("Users")]
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string UserName { get; set; } = string.Empty;
public bool IsActive { get; set; }
}
var generator = SqlGeneratorFactory.CreateSqlServer<User>();
var (sql, parameters) = generator.GetSelectAll(u => u.IsActive);
using var conn = new SqlConnection("Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True;");
var users = conn.Query<User>(sql, parameters).ToList();
使用扩展方法(IDbConnection)
using Microsoft.Data.SqlClient;
using SmartDapper.Extensions;
using var conn = new SqlConnection("Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True;");
var list = await conn.GetAllListAsync<User>(u => u.IsActive);
var (items, total) = await conn.GetPagedListAsync<User>(skip: 0, take: 20);
表达式树支持范围(WHERE / IN / LIKE / UPDATE SET)
SmartDapper 的“表达式树转 SQL”主要用于 Expression<Func<T, bool>>(WHERE 谓词),以及更新场景的 Expression<Func<T, object>>(SET 字段选择/赋值)。
WHERE(Expression<Func<T, bool>>)支持项
| 场景 | 示例表达式(C#) | SQL 形态(概念) | 备注 |
|---|---|---|---|
| 等值 / 不等 | x => x.Id == 1 / x => x.Id != 1 |
Id = @Id / Id <> @Id |
参数名默认按字段名生成 |
| 比较 | x => x.Age > 18 / >= / < / <= |
Age > @Age 等 |
仅支持比较运算符集合 |
| 逻辑组合 | x => x.IsActive && x.Age >= 18 |
(... ) AND (... ) |
支持 && / || |
| NULL 判断 | x => x.Name == null / != null |
Name IS NULL / IS NOT NULL |
仅对 == null / != null 特判 |
| bool 直接使用 | x => x.IsActive |
IsActive = @IsActive(true) |
避免生成裸列名导致 SQL 不可执行 |
| bool 取反 | x => !x.IsDeleted |
IsDeleted = 0 |
仅对实体 bool 字段取反做优化 |
| 字符串 Like | Contains/StartsWith/EndsWith |
LIKE @p |
仅支持 x => x.Column.Contains(value) 这类“实体字段在左侧”形态 |
| IN(集合包含) | x => ids.Contains(x.Id) |
Id IN (@Id_0, @Id_1, ...) |
仅支持 list.Contains(x.Property);空集合会生成 1 = 0 |
| All(全满足) | x => ages.All(a => x.Age >= a) |
展开为 AND 串 |
All(empty) 会生成 1 = 1(见下方安全限制) |
UPDATE 的 SET(Expression<Func<T, object>>)支持写法
适用于:
conn.UpdateSet<T>().Set(...)/conn.Update(updateFields, predicate)等。
| 写法 | 示例 | 建议 |
|---|---|---|
| 对象初始化器(推荐) | x => new User { Name = name, IsActive = true } |
表达力最强,支持常量/闭包变量 |
| 单字段 | x => x.Name |
支持,但通常仍需搭配明确赋值(更推荐对象初始化器) |
| 匿名 new | x => new { x.Name, x.IsActive } |
可用,但更像“字段选择”,不如对象初始化器语义清晰 |
典型不支持/慎用
| 类型 | 示例 | 说明 |
|---|---|---|
| 算术运算 | x => x.Age + 1 > 18 |
不支持(WHERE 二元运算仅处理比较与 AND/OR) |
| 未知方法调用 | x => x.Name.ToLower() == "a" |
不支持(仅支持 string 的 Contains/StartsWith/EndsWith) |
| 反向 Contains | x => x.Tags.Contains("a") |
不支持(仅支持 list.Contains(x.Prop)) |
安全限制(重要)
- UPDATE/DELETE 禁止恒真条件:例如
x => true、或All(empty)导致的1 = 1,会被拦截(防止误全表操作)。 - Fluent 查询限制:
Paging(skip, take)不能与自定义OrderBy(...)组合使用(分页 SQL 已内置排序规则)。- 投影查询(
Select(projection))不支持Paging(...),也不支持与SelectColumns(...)混用。
链式扩展(Fluent Builder)
SmartDapper 提供了一组面向 IDbConnection 的链式构建器,用于以“命令式链式 API”组织查询/插入/更新/删除,并在内部复用 SmartDapper 的 SQL 生成能力。
命名约定:
QuerySet<T>() / InsertSet<T>() / UpdateSet<T>() / DeleteSet<T>()。构建器对象非线程安全,建议按一次请求/一次操作创建并使用一次。
查询(Select)
using SmartDapper.Extensions;
// 1) 全字段查询 + Where + OrderBy
var list = await conn.QuerySet<User>()
.Where(u => u.IsActive && u.Age >= 18)
.OrderBy(u => u.Id, ascending: true)
.ToListAsync();
// 2) 指定列(两种方式:表达式/字符串)
var columns = await conn.QuerySet<User>()
.SelectColumns(u => new { u.Id, u.UserName })
.ToListAsync();
var columns2 = await conn.QuerySet<User>()
.Select("Id", "UserName")
.ToListAsync();
// 3) 投影(DTO/匿名类型)
var dtoList = await conn.QuerySet<User>()
.Select(u => new { u.Id, u.UserName })
.Where(u => u.IsActive)
.OrderBy(u => u.Id)
.ToListAsync();
删除(Delete)
// 1) 条件删除
var affected = await conn.DeleteSet<User>()
.Where(u => u.IsActive == false)
.ExecuteAsync();
// 2) 按主键删除
var affected2 = await conn.DeleteSet<User>()
.ByKey(1)
.ExecuteAsync();
插入(Insert)
// 1) 自动创建实体并填充
var newId = await conn.InsertSet<User>()
.Fill(u => { u.UserName = "Alice"; u.IsActive = true; })
.ExecuteAndGetIdAsync();
// 2) 基于已有实体实例
var user = new User { UserName = "Bob", IsActive = true };
await conn.InsertSet(user).ExecuteAsync();
更新(Update)
// 1) 推荐:对象初始化器(表达式树提取值)
var rows = await conn.UpdateSet<User>()
.Set(u => new User { UserName = "Alice", IsActive = true })
.Where(u => u.Id == 1)
.ExecuteAsync();
// 2) 也支持:匿名对象(字段名按“属性名/列名”处理)
var rows2 = await conn.UpdateSet<User>()
.Set(new { UserName = "Alice", IsActive = true })
.Where(u => u.Id == 1)
.ExecuteAsync();
Fluent 的已知限制/注意事项
- 分页与排序:
QuerySet<T>().Paging(skip, take)目前不支持与自定义OrderBy(...)同用(分页 SQL 已内置排序规则)。 - 投影限制:投影链(
Select(projection))目前不支持Paging(...),也不支持与SelectColumns(...)混用。 - First/Single:
FirstOrDefault()/SingleOrDefault()不会强制加TOP/LIMIT,仅对结果集做“取第一条/单条”的行为(多条命中时SingleOrDefault会抛异常)。
多数据库支持
- SQL Server:
SqlGeneratorFactory.CreateSqlServer<T>() - MySQL:
SqlGeneratorFactory.CreateMySql<T>() - SQLite:
SqlGeneratorFactory.CreateSqlite<T>()
相关包
SmartDapper.Repository:Repository + UnitOfWorkSmartDapper.Middleware:ASP.NET Core 中间件 + 声明式事务([UnitOfWork])
| Product | Versions 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 was computed. 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. |
-
net8.0
- Dapper (>= 2.1.66)
- Microsoft.Extensions.Logging (>= 9.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.10)
- Microsoft.Extensions.Logging.Console (>= 9.0.10)
- Microsoft.Extensions.ObjectPool (>= 9.0.10)
- System.ComponentModel.Annotations (>= 5.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SmartDapper:
| Package | Downloads |
|---|---|
|
SmartDapper.Repository
SmartDapper.Repository 提供通用的 Repository 抽象与 UnitOfWork 实现,封装常用 CRUD、分页和事务边界,帮助你用一致的方式组织数据访问层代码。 |
GitHub repositories
This package is not used by any popular GitHub repositories.