Skip to content

SqlSharp 总览

先建立整体心智模型,再按实体、上下文、查询、更新、集成几个主题逐步展开。

适用场景

  • 想用接近 ORM 的方式完成常见 CRUD,但又不想失去对 SQL 的控制
  • 需要变更跟踪,避免每次更新都手写整段 UPDATE
  • 既要支持链式查询,也要保留手写 SQL 的能力

核心问题

SqlSharp 是一组围绕数据库访问组织起来的能力,核心解决两件事:

  1. 把实体、查询、上下文这些代码结构映射成 SQL。
  2. 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() 生成并执行 SQL
  • find() 返回被跟踪的实体
  • 再次 saveChanges() 时只更新修改过的字段

依赖说明

包名作用
sqlsharpDbContextDbSet<T>Queryable<T>ChangeTracker
sqlsharp.macros@Entity@Model,并重导出 @Serialization
sqlsharp.annotations@Table@Column@Key@ConcurrencyCheck
sqlsharp.serialization查询结果映射和序列化相关类型
sqlsharp.convertersTypeMapperValueConverter
soulsoft_extensions_sqlsharp与依赖注入集成
mariadb.cdbc底层数据库驱动

通常最少需要:

  • sqlsharp
  • sqlsharp.macros
  • sqlsharp.annotations
  • 一个数据库驱动

学习顺序

推荐按下面的顺序阅读:

  1. 定义实体
  2. DbContext 配置
  3. 变更跟踪
  4. Queryable 查询
  5. 手写 SQL
  6. 事务
  7. 依赖注入集成
  8. 类型映射

模块关系

text
实体定义

DbContext 暴露 DbSet<T>

DbSet<T> / Queryable<T> 负责查询

ChangeTracker 负责跟踪实体变化

saveChanges() 统一生成并执行 SQL

把这个关系记住,后面的章节就会更容易读:

  • 查询主要看 DbSet<T>Queryable<T>
  • 更新主要看 ChangeTrackersaveChanges()
  • 运行时接入主要看 DbContext、DI、事务和类型映射

与其他模块组合

  • 在 Web 项目里,SqlSharp 通常和依赖注入一起使用,每个请求使用一个 DbContext
  • 在认证、授权、业务服务中,SqlSharp 负责持久化和查询,不替代领域建模
  • 在实际项目文档里,后续可以把 Blog、调度器等模块都建立在这套数据访问方式之上

相关专题

生产建议

  • 先把实体、上下文和最小 CRUD 跑通,再引入高级能力
  • 默认优先使用 Queryable 处理常规查询,复杂场景再落到手写 SQL
  • 需要长期维护的业务查询,尽量沉淀成扩展方法或仓储层,而不是散落在控制器里