SqlSharp 总览
先建立整体心智模型,再按实体、上下文、查询、更新、集成几个主题逐步展开。
适用场景
- 想用接近 ORM 的方式完成常见 CRUD,但又不想失去对 SQL 的控制
- 需要变更跟踪,避免每次更新都手写整段
UPDATE - 既要支持链式查询,也要保留手写 SQL 的能力
核心问题
SqlSharp 是一组围绕数据库访问组织起来的能力,核心解决两件事:
- 把实体、查询、上下文这些代码结构映射成 SQL。
- 用
ChangeTracker记录实体变化,在saveChanges()时只提交真正变化的列。
如果只看最小使用路径,可以把它理解成三个角色:
| 角色 | 作用 | 常见入口 |
|---|---|---|
| 实体 | 描述表结构和字段映射 | @Entity、@Serialization |
| 上下文 | 暴露 DbSet<T>,配置连接和模型 | DbContext |
| 操作接口 | 完成查询、增删改和提交 | DbSet<T>、saveChanges() |
快速开始
先看这三步:定义实体、定义 DbContext、执行 CRUD。
cangjie
import sqlsharp.*
import sqlsharp.macros.*
import sqlsharp.annotations.*
import sqlsharp.serialization.*
import mariadb.cdbc.*
@Entity
@Serialization
public class Product {
private var _id: Int64 = 0
private var _name: String = ""
private var _price: Int64 = 0
}
public class AppDbContext <: DbContext {
public prop products: DbSet<Product> {
get() { set<Product>() }
}
public override func onConfiguring(b: DbContextOptionsBuilder): Unit {
b.useMysql("mariadb://localhost:3306?username=root&password=1024&database=mydb", "mariadb")
}
}
main(): Int64 {
try (ctx = AppDbContext()) {
let p = Product(name: "Widget", price: 999)
ctx.add(p)
ctx.saveChanges()
let found = ctx.products.find([p.id]).getOrThrow()
found.price = 1099
ctx.saveChanges()
}
return 0
}这段代码已经覆盖了最小闭环:
add()把实体放入变更跟踪器saveChanges()生成并执行 SQLfind()返回被跟踪的实体- 再次
saveChanges()时只更新修改过的字段
依赖说明
| 包名 | 作用 |
|---|---|
sqlsharp | DbContext、DbSet<T>、Queryable<T>、ChangeTracker |
sqlsharp.macros | @Entity、@Model,并重导出 @Serialization |
sqlsharp.annotations | @Table、@Column、@Key、@ConcurrencyCheck 等 |
sqlsharp.serialization | 查询结果映射和序列化相关类型 |
sqlsharp.converters | TypeMapper、ValueConverter |
soulsoft_extensions_sqlsharp | 与依赖注入集成 |
mariadb.cdbc 等 | 底层数据库驱动 |
通常最少需要:
sqlsharpsqlsharp.macrossqlsharp.annotations- 一个数据库驱动
学习顺序
推荐按下面的顺序阅读:
模块关系
text
实体定义
↓
DbContext 暴露 DbSet<T>
↓
DbSet<T> / Queryable<T> 负责查询
↓
ChangeTracker 负责跟踪实体变化
↓
saveChanges() 统一生成并执行 SQL把这个关系记住,后面的章节就会更容易读:
- 查询主要看
DbSet<T>和Queryable<T> - 更新主要看
ChangeTracker和saveChanges() - 运行时接入主要看
DbContext、DI、事务和类型映射
与其他模块组合
- 在 Web 项目里,SqlSharp 通常和依赖注入一起使用,每个请求使用一个
DbContext - 在认证、授权、业务服务中,SqlSharp 负责持久化和查询,不替代领域建模
- 在实际项目文档里,后续可以把 Blog、调度器等模块都建立在这套数据访问方式之上
相关专题
- 如果你想看 SqlSharp 在真实项目里的组织方式,直接看 Blog 实战里的 SQLSharp 数据访问
- 如果你正在做定时任务,想知道任务如何复用
DbContext和数据访问层,再看 Scheduler 总览
生产建议
- 先把实体、上下文和最小 CRUD 跑通,再引入高级能力
- 默认优先使用
Queryable处理常规查询,复杂场景再落到手写 SQL - 需要长期维护的业务查询,尽量沉淀成扩展方法或仓储层,而不是散落在控制器里